5 unstable releases
0.3.1 | May 4, 2021 |
---|---|
0.3.0 | Oct 31, 2020 |
0.2.0 | Oct 27, 2020 |
0.1.1 | May 20, 2020 |
0.1.0 | Mar 21, 2020 |
#916 in Encoding
105KB
1.5K
SLoC
Dodo (pronounced doe doe
) is a very basic persistence library designed to be a quick and easy way to create a
persistent storage. It uses Serde under the hood to perform serialization of the
persisted data.
Usage
Add this to your Cargo.toml
:
[dependencies]
dodo = "0.3"
serde = { version = "1.0", features = ["derive"] }
uuid = { version = "0.8", features = ["serde", "v4"] }
Example
use std::error::Error;
use dodo::prelude::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
//The "Entity" derive implements the "Entity" trait for you.
#[derive(Debug, Entity, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Person {
//Every entity must have an "id" field of type "Option<Uuid>".
id: Option<Uuid>,
name: String,
age: u64,
}
//You should create a type for shorter names
type PersonCollection = Collection<Person, Directory, JsonSerializer>;
fn main() -> Result<(), Box<dyn Error>> {
// Create collection
let mut collection = PersonCollection::new(Directory::new("./person/collection")?);
//Clear collection
collection.clear()?;
// Add a person
let mut person = Person { id: None, name: "John Smith".into(), age: 42 };
collection.insert(&mut person)?;
// Get a person
let id = person.id.unwrap();
let mut person = collection.find(id)?;
// Find persons older than 20
let _persons = collection.find_all()?.filter(|person| person.age > 20).collect()?;
// Update a person
person.name = "Mary Smith".into();
collection.update(&person)?;
// Delete a person
collection.delete(person.id.unwrap())?;
Ok(())
}
Motivation
A full fledged database isn't always needed. Sometimes, it's too feature-rich for your needs. This is where Dodo comes in : basic data storage for basic applications.
On the other hand, when storing lots of data, with complex relations and complex queries, use your favorite database implementation, be it SQL or NoSQL. Dodo can't help in theses cases: it's not what it's meant for.
Dodo was not designed to be fast, nor efficient. The features you have right now might be the only features you'll ever have.
FAQ
What does Dodo means ?
In french, faire dodo
means to sleep
. In a way, this library puts data to sleep on a storage (like your hard
drive or SSD). It's also an extinct flightless bird.
Why do you return an error when something is not found ?
For better ergonomics. A Result<Option<T>>
can be quite cumbersome to use in iterators. This also makes match
statements less cluttered.
Why do I have to use a UUID
as an id for my entities ?
It's just simpler that way. Right now, it's the collection responsibility to assign an id to every entity it owns. Thus, the collection must have a way to generate new ids on the fly, which is not trivial for every type. This is why Dodo uses UUIDs : generating a new one is easy and very few collisions occurs.
Can I serialize my data in something else than JSON ?
Sure. Create your own implementation of the Serializer
trait, and you're done. Using Serde, you should be fine. You
can also use YAML if you activate the yaml
feature.
Changelog
See the CHANGELOG.md file for version details.
License
This project is licensed under the MIT License - see the LICENSE.md file for details
Dependencies
~0.9–1.9MB
~34K SLoC