#serialization #repository #derive-debug #collection #person #basic #entity

dodo

Basic persistence library designed to be a quick and easy way to create a persistent storage

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

#909 in Encoding

Download history 6/week @ 2024-02-26 89/week @ 2024-04-01

89 downloads per month

MIT license

105KB
1.5K SLoC

Dodo

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.8MB
~33K SLoC