Crates.io | entity |
lib.rs | entity |
version | 0.3.2 |
source | src |
created_at | 2020-11-08 05:37:09.023404 |
updated_at | 2021-04-24 06:36:58.562482 |
description | Library that provides entity-like constructs |
homepage | https://github.com/chipsenkbeil/entity-rs |
repository | https://github.com/chipsenkbeil/entity-rs |
max_upload_size | |
id | 309806 |
size | 310,795 |
A simplistic framework based on TAO, Facebook's distributed database for Social Graph.
Requires Rust 1.49+.
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.
[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:
[dependencies]
entity = { version = "0.3.0", features = ["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.
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.
use entity::EntLoader;
let db = /* entity::WeakDatabaseRc instance */;
// Loads the user from the provided database reference
let user = User::load_from_db_strict(db, 123).expect("Database available");
// Loads the user from the globally-set database
let user = User::load_strict(123).expect("Database available");
Every object implementing the Ent
trait is able to access a variety of
common data including abstract field information:
use entity::{Ent, Primitive, Value};
let user = /* User instance */;
// Access a list of all field names
assert_eq!(user.field_names(), vec![String::from("name"), String::from("age")]);
// Access individual field values, which are exposed using entity's
// generic Value enum
assert_eq!(user.field("name"), Some(Value::Text(/* ... */)));
assert_eq!(user.field("age"), Some(Value::Primitive(Primitive::Number(/* ... */))));
When using macros to generate an ent, typed accessors are also provided as seen below:
let user = /* User instance */;
// Accesses fields and returns a reference to their actual type NOT
// wrapped in entity's generic Value enum
assert_eq!(user.get_name(), &String::from("..."));
assert_eq!(user.get_age(), &123);
Every object implementing the Ent
trait is able to access a variety of
abstract edge information:
use entity::{Ent, EdgeValue};
let user = /* User instance */;
// Access a list of all edge names
assert_eq!(user.edge_names(), 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<Box<dyn Ent>>
let friends: Vec<Box<dyn Ent>> = user.load_edge("friends").expect("Database available");
When using macros to generate an ent, typed edge accessors are also provided as seen below:
let user = /* User instance */;
// Access the ids of ents referenced by the edge
assert_eq!(user.my_friends_ids(), vec![124, 125, /* ... */]);
// Load the ents referenced by the edge into memory
let friends: Vec<User> = user.load_friends().expect("Database available");
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:
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<Box<dyn Ent>> = Query::default()
.where_field("age", P::greater_than_or_equals(18))
.execute_with_db(db)
.expect("Database available");
// If the global database has been configured, can also be used in this manner
let ents: Vec<Box<dyn Ent>> = Query::default()
.where_field("age", P::greater_than_or_equals(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
:
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> = User::query()
.where_age(P::greater_than_or_equals(18))
.execute_with_db(db)
.expect("Database available");
// If the global database has been configured, can also be used in this manner
let users: Vec<User> = User::query()
.where_age(P::greater_than_or_equals(18))
.execute()
.expect("Database available");
async-graphql
:
example of using entity-rs
with async-graphql
inmemory
: example of using
entity-rs
with a custom inmemory databasesled
: example of using
entity-rs
with sled
Entity provides a few feature flags:
global
- Enables use of a database stored as a global variable,
providing shortcuts in creating and retrieving ents.macros
- Enables macros for deriving ents and exposing a cleaner
declarative API for ents. (Imports entity_macros
directly)serde-1
- Provides serde serialization module and associated functionality for ents
through the use of typetag. This will
require that all ents implement Serialize
and Deserialize.
serde
and typetag
to be included in dependencies.