entity-rs: Library & macros for entity data structures

Build Status Crates.io Docs.rs ![entity: rustc 1.49+] ![entity_macros: rustc 1.49+]

A simplistic framework based on TAO, Facebook's distributed database for Social Graph.

Requires Rust 1.49+.

Getting Started

Installation

Import Entity into your project by adding the following line to your Cargo.toml. entity_macros contains the macros needed to derive and/or transform your data to be compatible with supported databases and queries.

toml [dependencies] entity = "0.3.0"

For most use cases, you will want to also import the macros, which will bring in the entity_macros crate:

toml [dependencies] entity = { version = "0.3.0", features = ["macros"] }

Defining data using macros

The following is an example of defining a User data structure that contains an age and name field as well as references to many other User instances under the edge name friends.

```rust use entity::simple_ent;

[simple_ent]

struct User { name: String, age: u8,

#[ent(edge)]
friends: Vec<User>,

} ```

This generates a variety of trait implementations and additional data structures to work with the User struct against any database.

Loading an ent by id

```rust use entity::EntLoader;

let db = /* entity::WeakDatabaseRc instance */;

// Loads the user from the provided database reference let user = User::loadfromdb_strict(db, 123).expect("Database available");

// Loads the user from the globally-set database let user = User::load_strict(123).expect("Database available"); ```

Accessing ent fields

Every object implementing the Ent trait is able to access a variety of common data including abstract field information:

```rust use entity::{Ent, Primitive, Value};

let user = /* User instance */;

// Access a list of all field names asserteq!(user.fieldnames(), vec![String::from("name"), String::from("age")]);

// Access individual field values, which are exposed using entity's // generic Value enum asserteq!(user.field("name"), Some(Value::Text(/* ... */))); asserteq!(user.field("age"), Some(Value::Primitive(Primitive::Number(/* ... */)))); ```

When using macros to generate an ent, typed accessors are also provided as seen below:

```rust let user = /* User instance */;

// Accesses fields and returns a reference to their actual type NOT // wrapped in entity's generic Value enum asserteq!(user.getname(), &String::from("...")); asserteq!(user.getage(), &123); ```

Accessing ent edges

Every object implementing the Ent trait is able to access a variety of abstract edge information:

```rust use entity::{Ent, EdgeValue};

let user = /* User instance */;

// Access a list of all edge names asserteq!(user.edgenames(), vec![String::from("friends")]);

// Access specific edge information (does not load it) assert_eq!(user.edge("friends"), Some(EdgeValue::Many(vec![124, 125, /* ... */])));

// Load an edge by name, returning a Vec> let friends: Vec> = user.load_edge("friends").expect("Database available"); ```

When using macros to generate an ent, typed edge accessors are also provided as seen below:

```rust let user = /* User instance */;

// Access the ids of ents referenced by the edge asserteq!(user.myfriends_ids(), vec![124, 125, /* ... */]);

// Load the ents referenced by the edge into memory let friends: Vec = user.load_friends().expect("Database available"); ```

Querying an ent

Alongside loading ents by their ids, the full suite that entity-rs provides also includes the ability to query arbitrary data structures using a concept of queries and associated predicates:

```rust use entity::{EntQuery, Predicate as P, Query};

let db = /* WeakDatabaseRc instance */;

// Produce a new query to search for ents with an age field that is 18 or higher let ents: Vec> = Query::default() .wherefield("age", P::greaterthanorequals(18)) .executewithdb(db) .expect("Database available");

// If the global database has been configured, can also be used in this manner let ents: Vec> = Query::default() .wherefield("age", P::greaterthanorequals(18)) .execute() .expect("Database available"); ```

When using macros to generate an ent, a companion query struct that provides stricter types on queries is also created using the name {Ent}Query:

```rust use entity::{EntQuery, TypedPredicate as P};

let db = /* WeakDatabaseRc instance */;

// Produce a new query to search for ents with an age field that is 18 or higher let users: Vec = User::query() .whereage(P::greaterthanorequals(18)) .executewithdb(db) .expect("Database available");

// If the global database has been configured, can also be used in this manner let users: Vec = User::query() .whereage(P::greaterthanorequals(18)) .execute() .expect("Database available"); ```

Examples

Feature Flags

Entity provides a few feature flags: