What is structsy

Structsy is a simple embeddable database to persist structs and enums in Rust language.

Scope

Structsy has a simple API for store and retrieve data, using basics Rust constructs, without the use of any specific syntax or advanced construct, inspiration was taken from some mocking libraries that are injecting behaviour behind traits and structs, same approach is used in Structsy the logic for the persistence is injected using proc-macros, making the developer care only about rust code and hiding away all the persistence details.

Features

Struct persistence

Simple struct persistence with derive macros.

use structsy_derive::Persistent;

#[derive(Persistent)]
struct Example {
	desc :String,
}

Field Indexing

Allow to index fields for faster search, for more details on indexing check here

use structsy_derive::Persistent;

#[derive(Persistent)]
struct Example {
	#[index(mode="cluster")]
	desc :String,
}

Supported types

Are supported all the literal rust types, plus the String, Option and Vec, structsy::Ref

use structsy_derive::{Persistent, PersistentEmbedded};

#[derive(Persistent)]
struct Example {
	field_u8:u8,
	field_u16:u16,
	field_u32:u32,
	field_u64:u64,
	field_u128:u128,
	field_i8:i8,
	field_i16:i16,
	field_i32:i32,
	field_i64:i64,
	field_i128:i128,
	field_f32:f32,
	field_f64:f64,
	desc :String,
	reference_id:Ref<OtherStruct>,
	// All basic tipes are supported as value of the vector
	vec:Vec<u8>,
	// All basic tipes are supported as value of the option
	option:Option<u8>,
}

Embedded struct persistence

Allow to store struct inside other structs

use structsy_derive::{Persistent, PersistentEmbedded};

#[derive(Persistent)]
struct Example {
	desc :String,
	embedded: EmbeddedExample,
}

#[derive(PersistentEmbedded)]
struct EmbeddedExample {
	embedded_desc: String,
}

Enum persistence

Enum can be persisted, simple enum and enum with simple value are supported.

use structsy_derive::{Persistent, PersistentEmbedded};

#[derive(Persistent)]
enum Simple {
    First,
    Second,
}

#[derive(PersistentEmbedded)]
struct Embedded {
    desc:String,
}

#[derive(Persistent)]
enum Example {
    Embedded(Embedded),
    Value(String),
    None,
}

Transactions

Any data operation has to be inside a transaction, there is support for two phase commit in transactions.

//....
let mut tx = structsy.begin()?;
let id = tx.insert(Example::new("name"))?
tx.commit()?;
//...

Queries

For queries is enough to write a simple trait that describe the query logic and let structsy implement the logic

use structsy_derive::{Persistent, queries};

#[derive(Persistent)]
struct Example {
	desc :String,
}
#[queries(Example)]
trait ExampleQueries {
	 // The name of the method arguments should match the name of the struct fields.
	 fn search(self, desc:String) -> Self;
}
//.....

let query = structsy.query::<Example>().search("desc".to_string());

for (id, ele) in query.into_iter() {
	// inspect results here
}

//...

Projections

To describe projections are used simple structs that automatically map on existing struct using exactly the same fields of it.

use structsy_derive::{Projection, Persistent};

#[derive(Persistent)]
struct Person {
    name:String,
    surname:String,
}

#[derive(Projection)]
#[projection = "Person" ]
struct NameProjection {
    name:String,
}