Make more things burn less

This commit is contained in:
Nadja Reitzenstein 2021-10-28 01:10:35 +02:00
parent 150b2e68d9
commit 3231b51f89
15 changed files with 89 additions and 92 deletions

View File

@ -27,7 +27,6 @@ pub use typed::{
Adapter, Adapter,
OutputBuffer, OutputBuffer,
OutputWriter,
}; };
mod hash; 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> { pub struct AlignedAdapter<V> {
phantom: PhantomData<V>, phantom: PhantomData<V>,
} }
@ -136,6 +135,7 @@ impl<V: Serialize<AlignedSerializer<AlignedVec>>> Adapter for AlignedAdapter<V>
} }
} }
#[derive(Debug)]
pub struct Databases { pub struct Databases {
pub userdb: UserDB, pub userdb: UserDB,
pub passdb: PassDB, pub passdb: PassDB,

View File

@ -6,7 +6,10 @@ use std::{
BuildHasher, BuildHasher,
}, },
collections::hash_map::RandomState, collections::hash_map::RandomState,
fmt,
fmt::Debug,
}; };
use std::fmt::Formatter;
use rkyv::{ use rkyv::{
Archive, 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. /// The entry as it is stored inside the database.
pub struct Entry<K: Archive, V: Archive> { pub struct Entry<K: Archive, V: Archive> {
pub key: K, pub key: K,
@ -48,6 +51,12 @@ impl<K, A> HashAdapter<K, A> {
Self { k: PhantomData, a: PhantomData } 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: Fallible> Fallible for HashAdapter<K, A> { type Error = <A as Fallible>::Error; }
impl<K, A: Adapter> Adapter for HashAdapter<K, A> impl<K, A: Adapter> Adapter for HashAdapter<K, A>
@ -77,6 +86,16 @@ pub struct HashDB<A, K, H = RandomState>
hash_builder: H, 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> impl<A, K> HashDB<A, K>
{ {
pub unsafe fn create(env: &Environment, name: Option<&str>) -> lmdb::Result<Self> { pub unsafe fn create(env: &Environment, name: Option<&str>) -> lmdb::Result<Self> {

View File

@ -10,7 +10,7 @@ use super::Transaction;
use argon2; use argon2;
type Adapter = AllocAdapter<String>; type Adapter = AllocAdapter<String>;
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct PassDB { pub struct PassDB {
env: Arc<Environment>, env: Arc<Environment>,
db: DB<Adapter>, db: DB<Adapter>,

View File

@ -19,7 +19,7 @@ pub struct Resource {
description_idx: u64, description_idx: u64,
} }
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct ResourceDB { pub struct ResourceDB {
env: Arc<Environment>, env: Arc<Environment>,
db: DB<AllocAdapter<Resource>>, db: DB<AllocAdapter<Resource>>,

View File

@ -31,18 +31,28 @@ use lmdb::{
use super::RawDB; use super::RawDB;
/// Database Adapter to create a typed DB returning Rust types
pub trait Adapter: Fallible { pub trait Adapter: Fallible {
/// The serializer that will be instantiated to resolve the stored types
type Serializer: rkyv::ser::Serializer; type Serializer: rkyv::ser::Serializer;
/// Actual Value that will be extracted
type Value: Serialize<Self::Serializer>; type Value: Serialize<Self::Serializer>;
/// Create a new serializer
fn new_serializer() -> Self::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; 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; fn from_db_err(e: lmdb::Error) -> <Self as Fallible>::Error;
} }
struct AdapterPrettyPrinter<A: Adapter>(PhantomData<A>); struct AdapterPrettyPrinter<A: Adapter>(PhantomData<A>);
impl<A: Adapter> AdapterPrettyPrinter<A> { impl<A: Adapter> AdapterPrettyPrinter<A> {
pub fn new() -> Self { Self(PhantomData) } 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 { pub trait OutputBuffer {
/// The kind of buffer
type Buffer: AsRef<[u8]>; type Buffer: AsRef<[u8]>;
/// convert yourself into this buffer
fn into_slice(self) -> Self::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> { pub struct DB<A> {
db: RawDB, db: RawDB,
phantom: PhantomData<A>, phantom: PhantomData<A>,
@ -171,26 +179,7 @@ impl<'a, A> DB<A>
} }
} }
impl<'a, A> DB<A> #[derive(Debug)]
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)
}
}
pub struct TypedCursor<C, A> { pub struct TypedCursor<C, A> {
cursor: C, cursor: C,
phantom: PhantomData<A>, phantom: PhantomData<A>,
@ -218,6 +207,7 @@ impl<'txn, C, A> TypedCursor<C, A>
} }
} }
#[derive(Debug)]
pub struct Iter<'txn, A> { pub struct Iter<'txn, A> {
iter: lmdb::Iter<'txn>, iter: lmdb::Iter<'txn>,
phantom: PhantomData<A>, phantom: PhantomData<A>,

View File

@ -6,7 +6,7 @@ use crate::db::{DatabaseFlags, LMDBorrow, RoTransaction, WriteFlags, };
use rkyv::{Archive, Serialize, Deserialize, Archived}; use rkyv::{Archive, Serialize, Deserialize, Archived};
type Adapter = AllocAdapter<User>; type Adapter = AllocAdapter<User>;
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct UserDB { pub struct UserDB {
env: Arc<Environment>, env: Arc<Environment>,
db: DB<Adapter>, db: DB<Adapter>,

View File

@ -1,6 +1,5 @@
use std::io; use std::io;
use std::fmt; use std::fmt;
use serde_dhall;
use rsasl::SaslError; use rsasl::SaslError;
@ -9,8 +8,8 @@ use crate::db::DBError;
//FIXME use crate::network; //FIXME use crate::network;
#[derive(Debug)] #[derive(Debug)]
/// Shared error type
pub enum Error { pub enum Error {
Dhall(serde_dhall::Error),
SASL(SaslError), SASL(SaslError),
IO(io::Error), IO(io::Error),
Boxed(Box<dyn std::error::Error>), Boxed(Box<dyn std::error::Error>),
@ -22,9 +21,6 @@ pub enum Error {
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
Error::Dhall(e) => {
write!(f, "Dhall coding error: {}", e)
},
Error::SASL(e) => { Error::SASL(e) => {
write!(f, "SASL Error: {}", 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 { impl From<Box<dyn std::error::Error>> for Error {
fn from(e: Box<dyn std::error::Error>) -> Error { fn from(e: Box<dyn std::error::Error>) -> Error {
Error::Boxed(e) Error::Boxed(e)
@ -81,6 +71,4 @@ impl From<DBError> for Error {
fn from(e: DBError) -> Error { fn from(e: DBError) -> Error {
Error::DB(e) Error::DB(e)
} }
} }
pub(crate) type Result<T> = std::result::Result<T, Error>;

View File

@ -1,14 +1,26 @@
#![forbid(unused_imports)] #![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; pub mod db;
/// Shared error type
pub mod error; pub mod error;
pub mod network;
pub mod oid; pub mod oid;
/// Policy decision engine
pub mod permissions; pub mod permissions;
/// Resources
pub mod resource; pub mod resource;
/// State of Resources
pub mod state; pub mod state;
/// Varints
pub mod varint; pub mod varint;
use intmap::IntMap; use intmap::IntMap;

View File

@ -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>,
}

View File

@ -293,23 +293,6 @@ fn parse_string_first_node(first_child_node: &str) -> Result<u8, ObjectIdentifie
Ok(first_child_node) 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 { impl ObjectIdentifier {
fn from_string<S>(value: S) -> Result<ObjectIdentifier, ObjectIdentifierError> fn from_string<S>(value: S) -> Result<ObjectIdentifier, ObjectIdentifierError>
where where
@ -512,7 +495,7 @@ pub(crate) mod tests {
pub(crate) fn gen_random() -> ObjectIdentifier { pub(crate) fn gen_random() -> ObjectIdentifier {
let amt: u8 = rand::random::<u8>() % 10 + 1; let amt: u8 = rand::random::<u8>() % 10 + 1;
let mut children = Vec::new(); let mut children = Vec::new();
for i in 0..amt { for _ in 0..amt {
children.push(rand::random()); children.push(rand::random());
} }
@ -868,6 +851,31 @@ pub(crate) mod tests {
assert_eq!(expected, actual); 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] #[test]
fn encode_to_string() { fn encode_to_string() {
let expected = String::from("1.2.3.4"); let expected = String::from("1.2.3.4");

View File

@ -64,6 +64,7 @@ pub enum Error {
} }
// TODO: more message context // TODO: more message context
#[derive(Debug)]
pub struct Update { pub struct Update {
pub state: State, pub state: State,
pub errchan: Sender<Error>, pub errchan: Sender<Error>,

View File

@ -73,6 +73,7 @@ impl fmt::Debug for State {
} }
} }
#[derive(Debug)]
pub struct StateBuilder { pub struct StateBuilder {
hasher: DefaultHasher, hasher: DefaultHasher,
inner: Vec<OwnedEntry> inner: Vec<OwnedEntry>

View File

@ -380,6 +380,7 @@ impl ImplData<'_> {
} }
} }
#[derive(Debug)]
pub struct ImplEntry<'a> { pub struct ImplEntry<'a> {
id: ImplId<'a>, id: ImplId<'a>,
data: ImplData<'a>, data: ImplData<'a>,

View File

@ -1,6 +1,7 @@
use std::default::Default; use std::default::Default;
use std::ops::{Deref}; use std::ops::{Deref};
#[derive(Debug)]
pub struct VarUInt<const N: usize> { pub struct VarUInt<const N: usize> {
offset: usize, offset: usize,
bytes: [u8; N], bytes: [u8; N],

View File

@ -75,7 +75,8 @@ fn main() -> Result<(), Error> {
// If no `config` option is given use a preset default. // If no `config` option is given use a preset default.
let configpath = matches.value_of("config").unwrap_or("/etc/diflouroborane.dhall"); 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); println!("{:#?}", config);
let mut sockaddrs = Vec::new(); let mut sockaddrs = Vec::new();