plabayo / venndb

in memory Rust database to query your data like a Venn diagram
https://venndb.rs
Apache License 2.0
91 stars 1 forks source link

allow for a row to be validated with custom logic prior to appending it (in any way) #8

Closed GlenDC closed 6 months ago

GlenDC commented 6 months ago

Rust's type system helps a lot with validation, given plenty of assumptions and requirements can be registered within the used types. At times however the combination of properties give meaning as a group, where some combinations make sense and others not. Enums (sum types) are what help usually in this situation. However it is not always a desired one, and in the case of venndb it doesn't play very well with the rest of the setup. As such for that reason and others it can be useful to allow for a custom validation of a row prior to appending it, such that one can guarantee that any appended rows do fulfill all required requirements.

Example:

#[derive(Debug, VennDB)]
#[venndb(name = "MyDB", validatator = "my_validator_fn")]
pub struct Value {
   pub foo: String,
   pub bar: u32,
}

fn my_validator_fn(value: &Value) -> bool {
    !foo.is_empty() && value.bar > 0
}

let mut db = MyDB::default();
assert!(db.append(Value {
    foo: "".to_owned(),
    bar: 42,
}).is_err()); // fails because foo == empty

The above example illustrates that the type system can only bring you so far. Of course one can argue that a NewType can solve this particular issue by only allowing the newtype instances to be created with values that match such conditions. And this is true.

However, what if the legal value space of a column depends upon the specific value of another? E.g. what is foo can be empty when bar is 2. This becomes a lot more difficult, and given the large space that unsigned integers are composed from it might also become impossible to abstract such rules in a sum type. If desired at all of course, given it would also make the usage of it within a venndb-derived db more difficult.