Crate klub_models[][src]

Expand description

Centralized library containing all data models.

Models are used to describe entities and relationships. Each model has a unique schema and is a mod in this package.

View all current models and relationships schemas

The advantages of making each model a mod in a centralized lib are:

  • Version control models
  • Can be shared across numerous rust repos
  • GraphQL schemas are generated using the structs and traits defined in this lib
  • Front-end repos can also use this lib to generate typescript types if built for wasm targets
  • Code re-usability and less maintainance

Easily construct a model

let problem = Problem::new(id, name);

Up cast models to their super class.

.into() is used to cast Problem to Topic

let problem = Problem::new(id, name);
let topic = Some(problem.clone().into()); // topic is problem's super class

match against them. Every model mode with sub classes declares an enum deriving strum crate macros. Strum makes it easy to cast strings to enums and vice versa. This make is easy to match strings against emums.

let model_name_as_enum = TopicType::from_str(&model_name).unwrap();
match model_name_as_enum {
    TopicType::Problem => {
        let problem = Problem::new(id_str, name_str, &["2000"], &["8000"]);
        return Some(problem.clone().into());
    }
    TopicType::Discussion => {
        let discussion = Discussion::new(id_str, name_str, &["2000"], &["8000"]);
        return Some(discussion.clone().into());
    }
}

Now let’s put it all together.

In this example we are getting a topic from Neo4J graph database. We then serialize the query response neo4rs::Node to a topic manually. We then cast the Neo4J node’s model_name to a TopicType enum. We then match against the TopicTypes and construct either a Problem or a Discussion. Lastly we up cast the Problem/Discussion to being a Topic.

use klub_models::topic::topic::{TopicType, TopicValue, TOPIC_MODEL_ALIAS, TOPIC_MODEL_NAME};

...

// Example GraphQL topic field resolver
async fn topic(
 #[graphql(context)] ctx: &GraphContext,
 #[graphql(description = "id of topic")] id: String,
 ) -> Option<TopicValue> {
 let model_params = ModelParams {
  model_name: TOPIC_MODEL_NAME,
  model_alias: TOPIC_MODEL_ALIAS,
};
let id_str = &id[..];
let topic_node = &ctx.find_one_by_id(model_params, id_str).await.unwrap();

let name: String = topic_node.get("name").unwrap();
let name_str = &name[..];
let model_name: String = topic_node.get("model_name").unwrap();
let model_name_as_enum = TopicType::from_str(&model_name).unwrap();

match model_name_as_enum {
 TopicType::Problem => {
      let problem = Problem::new(id_str, name_str, &["2000"], &["8000"]);
      return Some(problem.clone().into());
  }
  TopicType::Discussion => {
      let discussion = Discussion::new(id_str, name_str, &["2000"], &["8000"]);
      return Some(discussion.clone().into());
  }
 }
}

Modules

Macros