mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-10 17:43:23 +01:00
Make more things burn less
This commit is contained in:
parent
150b2e68d9
commit
3231b51f89
@ -27,7 +27,6 @@ pub use typed::{
|
||||
|
||||
Adapter,
|
||||
OutputBuffer,
|
||||
OutputWriter,
|
||||
};
|
||||
|
||||
mod hash;
|
||||
@ -112,7 +111,7 @@ impl<V: Serialize<Ser>> Adapter for AllocAdapter<V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct AlignedAdapter<V> {
|
||||
phantom: PhantomData<V>,
|
||||
}
|
||||
@ -136,6 +135,7 @@ impl<V: Serialize<AlignedSerializer<AlignedVec>>> Adapter for AlignedAdapter<V>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Databases {
|
||||
pub userdb: UserDB,
|
||||
pub passdb: PassDB,
|
||||
|
@ -6,7 +6,10 @@ use std::{
|
||||
BuildHasher,
|
||||
},
|
||||
collections::hash_map::RandomState,
|
||||
fmt,
|
||||
fmt::Debug,
|
||||
};
|
||||
use std::fmt::Formatter;
|
||||
|
||||
use rkyv::{
|
||||
Archive,
|
||||
@ -31,7 +34,7 @@ use super::{
|
||||
};
|
||||
|
||||
|
||||
#[derive(Archive, Serialize, Deserialize)]
|
||||
#[derive(Archive, Serialize, Deserialize, Debug)]
|
||||
/// The entry as it is stored inside the database.
|
||||
pub struct Entry<K: Archive, V: Archive> {
|
||||
pub key: K,
|
||||
@ -48,6 +51,12 @@ impl<K, A> HashAdapter<K, A> {
|
||||
Self { k: PhantomData, a: PhantomData }
|
||||
}
|
||||
}
|
||||
impl<K, A> Debug for HashAdapter<K, A> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
use core::any::type_name;
|
||||
write!(f, "HashAdapter<{}, {}>", type_name::<K>(), type_name::<A>())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, A: Fallible> Fallible for HashAdapter<K, A> { type Error = <A as Fallible>::Error; }
|
||||
impl<K, A: Adapter> Adapter for HashAdapter<K, A>
|
||||
@ -77,6 +86,16 @@ pub struct HashDB<A, K, H = RandomState>
|
||||
hash_builder: H,
|
||||
}
|
||||
|
||||
impl<A: Adapter, K, H: Debug> fmt::Debug for HashDB<A, K, H> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let adapter = HashAdapter::<A,K>::new();
|
||||
f.debug_struct("HashDB")
|
||||
.field("db", &adapter)
|
||||
.field("hasher", &self.hash_builder)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, K> HashDB<A, K>
|
||||
{
|
||||
pub unsafe fn create(env: &Environment, name: Option<&str>) -> lmdb::Result<Self> {
|
||||
|
@ -10,7 +10,7 @@ use super::Transaction;
|
||||
use argon2;
|
||||
|
||||
type Adapter = AllocAdapter<String>;
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PassDB {
|
||||
env: Arc<Environment>,
|
||||
db: DB<Adapter>,
|
||||
|
@ -19,7 +19,7 @@ pub struct Resource {
|
||||
description_idx: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ResourceDB {
|
||||
env: Arc<Environment>,
|
||||
db: DB<AllocAdapter<Resource>>,
|
||||
|
@ -31,18 +31,28 @@ use lmdb::{
|
||||
|
||||
use super::RawDB;
|
||||
|
||||
/// Database Adapter to create a typed DB returning Rust types
|
||||
pub trait Adapter: Fallible {
|
||||
/// The serializer that will be instantiated to resolve the stored types
|
||||
type Serializer: rkyv::ser::Serializer;
|
||||
/// Actual Value that will be extracted
|
||||
type Value: Serialize<Self::Serializer>;
|
||||
|
||||
/// Create a new serializer
|
||||
fn new_serializer() -> Self::Serializer;
|
||||
|
||||
/// Convert any Serializer Error in your shared error.
|
||||
///
|
||||
/// You *must* implement this if you don't use `Infallible` as Supertrait.
|
||||
fn from_ser_err(e: <Self::Serializer as Fallible>::Error) -> <Self as Fallible>::Error;
|
||||
|
||||
/// Convert the Database Error type into your shared error.
|
||||
// TODO: Extract both conversion into their own trait because there's a sensible impl for
|
||||
// `Infallible` for both.
|
||||
fn from_db_err(e: lmdb::Error) -> <Self as Fallible>::Error;
|
||||
}
|
||||
|
||||
struct AdapterPrettyPrinter<A: Adapter>(PhantomData<A>);
|
||||
|
||||
impl<A: Adapter> AdapterPrettyPrinter<A> {
|
||||
pub fn new() -> Self { Self(PhantomData) }
|
||||
}
|
||||
@ -56,8 +66,11 @@ impl<A: Adapter> fmt::Debug for AdapterPrettyPrinter<A> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserialize adapter to write into an Buffer
|
||||
pub trait OutputBuffer {
|
||||
/// The kind of buffer
|
||||
type Buffer: AsRef<[u8]>;
|
||||
/// convert yourself into this buffer
|
||||
fn into_slice(self) -> Self::Buffer;
|
||||
}
|
||||
|
||||
@ -68,11 +81,6 @@ impl<const N: usize> OutputBuffer for AllocSerializer<N> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This should be possible to autoimplement for Sized Serializers
|
||||
pub trait OutputWriter: Fallible {
|
||||
fn write_into(&mut self, buf: &mut [u8]) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
pub struct DB<A> {
|
||||
db: RawDB,
|
||||
phantom: PhantomData<A>,
|
||||
@ -171,26 +179,7 @@ impl<'a, A> DB<A>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, A> DB<A>
|
||||
where A: Adapter,
|
||||
A::Serializer: OutputWriter,
|
||||
{
|
||||
pub fn put_nocopy<K: AsRef<[u8]>>(&self, txn: &mut RwTransaction, key: &K, val: &A::Value, flags: WriteFlags)
|
||||
-> Result<usize, A::Error>
|
||||
{
|
||||
let mut serializer = A::new_serializer();
|
||||
let pos = serializer.serialize_value(val)
|
||||
.map_err(A::from_ser_err)?;
|
||||
|
||||
let mut buf = self.db.reserve(txn, &key.as_ref(), pos, flags)
|
||||
.map_err(A::from_db_err)?;
|
||||
serializer.write_into(&mut buf)
|
||||
.map_err(A::from_ser_err)?;
|
||||
|
||||
Ok(pos)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TypedCursor<C, A> {
|
||||
cursor: C,
|
||||
phantom: PhantomData<A>,
|
||||
@ -218,6 +207,7 @@ impl<'txn, C, A> TypedCursor<C, A>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Iter<'txn, A> {
|
||||
iter: lmdb::Iter<'txn>,
|
||||
phantom: PhantomData<A>,
|
||||
|
@ -6,7 +6,7 @@ use crate::db::{DatabaseFlags, LMDBorrow, RoTransaction, WriteFlags, };
|
||||
use rkyv::{Archive, Serialize, Deserialize, Archived};
|
||||
|
||||
type Adapter = AllocAdapter<User>;
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UserDB {
|
||||
env: Arc<Environment>,
|
||||
db: DB<Adapter>,
|
||||
|
@ -1,6 +1,5 @@
|
||||
use std::io;
|
||||
use std::fmt;
|
||||
use serde_dhall;
|
||||
|
||||
use rsasl::SaslError;
|
||||
|
||||
@ -9,8 +8,8 @@ use crate::db::DBError;
|
||||
//FIXME use crate::network;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Shared error type
|
||||
pub enum Error {
|
||||
Dhall(serde_dhall::Error),
|
||||
SASL(SaslError),
|
||||
IO(io::Error),
|
||||
Boxed(Box<dyn std::error::Error>),
|
||||
@ -22,9 +21,6 @@ pub enum Error {
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Error::Dhall(e) => {
|
||||
write!(f, "Dhall coding error: {}", e)
|
||||
},
|
||||
Error::SASL(e) => {
|
||||
write!(f, "SASL Error: {}", e)
|
||||
},
|
||||
@ -59,12 +55,6 @@ impl From<io::Error> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_dhall::Error> for Error {
|
||||
fn from(e: serde_dhall::Error) -> Error {
|
||||
Error::Dhall(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<dyn std::error::Error>> for Error {
|
||||
fn from(e: Box<dyn std::error::Error>) -> Error {
|
||||
Error::Boxed(e)
|
||||
@ -82,5 +72,3 @@ impl From<DBError> for Error {
|
||||
Error::DB(e)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
16
bffhd/lib.rs
16
bffhd/lib.rs
@ -1,14 +1,26 @@
|
||||
#![forbid(unused_imports)]
|
||||
#![warn(missing_docs, missing_debug_implementations)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
|
||||
//! Diflouroborane
|
||||
//!
|
||||
//! This is the server component of the FabAccess project.
|
||||
//! The entry point of bffhd can be found in [bin/bffhd/main.rs](../bin/bffhd/main.rs)
|
||||
//!
|
||||
//! P.S.: If you're curious about the name; the project was initially called "Better Fablab
|
||||
//! Friend and Helper" (BFFH). And the chemical formula of Diflouroborane is BF2H.
|
||||
|
||||
/// Internal Databases build on top of LMDB, a mmap()'ed B-tree DB optimized for reads
|
||||
pub mod db;
|
||||
/// Shared error type
|
||||
pub mod error;
|
||||
pub mod network;
|
||||
pub mod oid;
|
||||
/// Policy decision engine
|
||||
pub mod permissions;
|
||||
/// Resources
|
||||
pub mod resource;
|
||||
/// State of Resources
|
||||
pub mod state;
|
||||
/// Varints
|
||||
pub mod varint;
|
||||
|
||||
use intmap::IntMap;
|
||||
|
@ -1,25 +0,0 @@
|
||||
use std::{
|
||||
sync::Arc,
|
||||
collections::HashMap,
|
||||
};
|
||||
|
||||
use futures_signals::signal::{
|
||||
Mutable,
|
||||
MutableSignalCloned
|
||||
};
|
||||
|
||||
use crate::state::State;
|
||||
|
||||
type ResourceState = Mutable<Arc<State>>;
|
||||
type ResourceStateSignal = MutableSignalCloned<Arc<State>>;
|
||||
|
||||
/// Connection Broker between Resources and Subscribers
|
||||
///
|
||||
/// This serves as touch-off point between resources and anybody else. It doesn't drive
|
||||
/// any state updates, it only allows subscribers to subscribe to the resources that are
|
||||
/// driving the state updates
|
||||
pub struct Network {
|
||||
sources: HashMap<u64, ResourceState>,
|
||||
}
|
||||
|
||||
|
44
bffhd/oid.rs
44
bffhd/oid.rs
@ -293,23 +293,6 @@ fn parse_string_first_node(first_child_node: &str) -> Result<u8, ObjectIdentifie
|
||||
Ok(first_child_node)
|
||||
}
|
||||
|
||||
fn parse_string_child_node(
|
||||
node_str: &str,
|
||||
out: &mut Vec<u8>
|
||||
) -> Result<(), ObjectIdentifierError> {
|
||||
let node: Node = node_str.parse()
|
||||
.map_err(|_| ObjectIdentifierError::IllegalChildNodeValue)?;
|
||||
// TODO bench against !*node &= 0x80, compiler may already optimize better
|
||||
if node <= 127 {
|
||||
out.push(node as u8);
|
||||
} else {
|
||||
let vi: VarNode = node.into();
|
||||
out.extend_from_slice(vi.as_bytes());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl ObjectIdentifier {
|
||||
fn from_string<S>(value: S) -> Result<ObjectIdentifier, ObjectIdentifierError>
|
||||
where
|
||||
@ -512,7 +495,7 @@ pub(crate) mod tests {
|
||||
pub(crate) fn gen_random() -> ObjectIdentifier {
|
||||
let amt: u8 = rand::random::<u8>() % 10 + 1;
|
||||
let mut children = Vec::new();
|
||||
for i in 0..amt {
|
||||
for _ in 0..amt {
|
||||
children.push(rand::random());
|
||||
}
|
||||
|
||||
@ -868,6 +851,31 @@ pub(crate) mod tests {
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_string_large_children_ok() {
|
||||
let expected =
|
||||
ObjectIdentifier::build(ObjectIdentifierRoot::JointIsoItuT,
|
||||
25,
|
||||
vec![190754093376743485973207716749546715206,
|
||||
255822649272987943607843257596365752308,
|
||||
15843412533224453995377625663329542022,
|
||||
6457999595881951503805148772927347934,
|
||||
19545192863105095042881850060069531734,
|
||||
195548685662657784196186957311035194990,
|
||||
233020488258340943072303499291936117654,
|
||||
193307160423854019916786016773068715190,
|
||||
]).unwrap();
|
||||
let actual = "2.25.190754093376743485973207716749546715206.\
|
||||
255822649272987943607843257596365752308.\
|
||||
15843412533224453995377625663329542022.\
|
||||
6457999595881951503805148772927347934.\
|
||||
19545192863105095042881850060069531734.\
|
||||
195548685662657784196186957311035194990.\
|
||||
233020488258340943072303499291936117654.\
|
||||
193307160423854019916786016773068715190".try_into().unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn encode_to_string() {
|
||||
let expected = String::from("1.2.3.4");
|
||||
|
@ -64,6 +64,7 @@ pub enum Error {
|
||||
}
|
||||
|
||||
// TODO: more message context
|
||||
#[derive(Debug)]
|
||||
pub struct Update {
|
||||
pub state: State,
|
||||
pub errchan: Sender<Error>,
|
||||
|
@ -73,6 +73,7 @@ impl fmt::Debug for State {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct StateBuilder {
|
||||
hasher: DefaultHasher,
|
||||
inner: Vec<OwnedEntry>
|
||||
|
@ -380,6 +380,7 @@ impl ImplData<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ImplEntry<'a> {
|
||||
id: ImplId<'a>,
|
||||
data: ImplData<'a>,
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::default::Default;
|
||||
use std::ops::{Deref};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VarUInt<const N: usize> {
|
||||
offset: usize,
|
||||
bytes: [u8; N],
|
||||
|
@ -75,7 +75,8 @@ fn main() -> Result<(), Error> {
|
||||
|
||||
// If no `config` option is given use a preset default.
|
||||
let configpath = matches.value_of("config").unwrap_or("/etc/diflouroborane.dhall");
|
||||
let config = config::read(&PathBuf::from_str(configpath).unwrap())?;
|
||||
let config = config::read(&PathBuf::from_str(configpath).unwrap())
|
||||
.expect("Failed to parse config");
|
||||
println!("{:#?}", config);
|
||||
|
||||
let mut sockaddrs = Vec::new();
|
||||
|
Loading…
Reference in New Issue
Block a user