### Interact with DynamoDB Entities using EntityExt in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md Demonstrates common data manipulation operations on DynamoDB entities using the `EntityExt` trait. This includes methods for upserting (`put`), creating (`create`), replacing (`replace`), deleting (`delete`), getting (`get`), and updating (`update`) entity instances. ```Rust # struct Database; # impl modyne::Table for Database { # type PrimaryKey = modyne::keys::Primary; # type IndexKeys = (); # fn table_name(&self) -> &str {unimplemented!()} # fn client(&self) -> &aws_sdk_dynamodb::Client {unimplemented!()} # } # #[derive(Debug, modyne::EntityDef, serde::Serialize)] # struct Session {user_id: String,session_token: String} # impl modyne::Entity for Session { # type KeyInput<'a> = &'a str; # type Table = Database; # type IndexKeys = (); # fn primary_key(input: Self::KeyInput<'_>) -> modyne::keys::Primary {modyne::keys::Primary { hash: String::new(), range: String::new() }} # fn full_key(&self) -> modyne::keys::FullKey {modyne::keys::FullKey { primary:Self::primary_key(""), indexes:()}} # } use modyne::EntityExt; let mk_session = || Session { session_token: String::from("session-1"), user_id: String::from("user-1"), }; let upsert = mk_session().put(); let create = mk_session().create(); let replace = mk_session().replace(); let delete = Session::delete("session-1"); let get = Session::get("session-1"); let update = Session::update("session-1"); ``` -------------------------------- ### Define DynamoDB Table Trait in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md Demonstrates how to define a DynamoDB table by implementing the `Table` trait in Rust. This involves exposing the table's name, a configured AWS DynamoDB client, and relevant primary and index keys for `modyne` to access. The example includes a global secondary index. ```Rust use modyne::{keys, Table}; struct Database { table_name: String, client: aws_sdk_dynamodb::Client, } impl Table for Database { type PrimaryKey = keys::Primary; type IndexKeys = keys::Gsi1; fn table_name(&self) -> &str { &self.table_name } fn client(&self) -> &aws_sdk_dynamodb::Client { &self.client } } ``` -------------------------------- ### Setting up Entities for Modyne Aggregates and Queries in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This Rust code snippet introduces the setup for using Modyne's aggregates and queries for efficient data retrieval from DynamoDB. It defines the necessary `Database` and `Session` entities, including their `Table` and `Entity` trait implementations, which are prerequisites for performing range queries and processing multiple entities. ```Rust # struct Database; # impl modyne::Table for Database { # type PrimaryKey = keys::Primary; # type IndexKeys = keys::Gsi1; # fn table_name(&self) -> &str {unimplemented!()} # fn client(&self) -> &aws_sdk_dynamodb::Client {unimplemented!()} # } # # #[derive(Debug, modyne::EntityDef, serde::Serialize, serde::Deserialize)] # struct Session {user_id: String,session_token: String} # impl modyne::Entity for Session { # type KeyInput<'a> = &'a str; # type Table = Database; # type IndexKeys = modyne::keys::Gsi1; # fn primary_key(input: Self::KeyInput<'_>) -> modyne::keys::Primary {unimplemented!()} # fn full_key(&self) -> modyne::keys::FullKey {unimplemented!()} # } # # #[derive(Debug, modyne::EntityDef, serde::Serialize, serde::Deserialize)] # struct UserMetadata {user_id: String} # impl modyne::Entity for UserMetadata { # type KeyInput<'a> = &'a str; # type Table = Database; # type IndexKeys = modyne::keys::Gsi1; ``` -------------------------------- ### Defining a Read-Only Entity Projection in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This Rust code snippet demonstrates how to define a `Projection` using Modyne's derive macro. It shows how to create a `SessionTokenOnly` projection from a `Session` entity, allowing access to only a subset of the entity's attributes. The example includes necessary boilerplate for `EntityDef` and `Table` implementations. ```Rust use modyne::{EntityDef, Projection}; # struct Database; # impl modyne::Table for Database { # type PrimaryKey = modyne::keys::Primary; # type IndexKeys = modyne::keys::Gsi1; # fn table_name(&self) -> &str {unimplemented!()} # fn client(&self) -> &aws_sdk_dynamodb::Client {unimplemented!()} # } # # impl modyne::Entity for Session { # type KeyInput<'a> = &'a str; # type Table = Database; # type IndexKeys = modyne::keys::Gsi1; # fn primary_key(input: Self::KeyInput<'_>) -> modyne::keys::Primary {unimplemented!()} # fn full_key(&self) -> modyne::keys::FullKey {unimplemented!()} # } #[derive(Debug, EntityDef, serde::Serialize, serde::Deserialize)] struct Session { user_id: String, session_token: String, } #[derive(Debug, Projection, serde::Deserialize)] #[entity(Session)] struct SessionTokenOnly { session_token: String, } ``` -------------------------------- ### Handling Projection Field Mismatch Errors in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This example illustrates a common compile-time error when defining a `Projection` in Modyne: a field name in the projection struct (`session`) does not match any field in the source entity (`Session`). This demonstrates the built-in validation of the `Projection` derive macro, which prevents incorrect attribute mapping. ```Rust # use modyne::{EntityDef, Projection}; # struct Database; # impl modyne::Table for Database { # type PrimaryKey = modyne::keys::Primary; # type IndexKeys = modyne::keys::Gsi1; # fn table_name(&self) -> &str {unimplemented!()} # fn client(&self) -> &aws_sdk_dynamodb::Client {unimplemented!()} # } # # impl modyne::Entity for Session { # type KeyInput<'a> = &'a str; # type Table = Database; # type IndexKeys = modyne::keys::Gsi1; # fn primary_key(input: Self::KeyInput<'_>) -> modyne::keys::Primary {unimplemented!()} # fn full_key(&self) -> modyne::keys::FullKey {unimplemented!()} # } # # #[derive(Debug, EntityDef, serde::Serialize, serde::Deserialize)] # struct Session { # user_id: String, # session_token: String, # } # #[derive(Debug, Projection, serde::Deserialize)] #[entity(Session)] struct SessionTokenOnly { session: String, } ``` -------------------------------- ### Define DynamoDB Entity with Primary and Index Keys in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md Shows how to define an entity that represents a single item in a DynamoDB table. Entities share the table's primary key and can participate in secondary indexes. The example uses `EntityDef` derive macro and implements the `Entity` trait to define primary and full keys. ```Rust use modyne::{keys, Entity, EntityDef}; # # struct Database; # # impl modyne::Table for Database { # type PrimaryKey = keys::Primary; # type IndexKeys = keys::Gsi1; # fn table_name(&self) -> &str {unimplemented!()} # fn client(&self) -> &aws_sdk_dynamodb::Client {unimplemented!()} # } #[derive(Debug, EntityDef, serde::Serialize, serde::Deserialize)] struct Session { user_id: String, session_token: String, } impl Entity for Session { type KeyInput<'a> = &'a str; type Table = Database; type IndexKeys = keys::Gsi1; fn primary_key(input: Self::KeyInput<'_>) -> keys::Primary { keys::Primary { hash: format!("SESSION#{}", input), range: format!("SESSION#{}", input), } } fn full_key(&self) -> keys::FullKey { keys::FullKey { primary: Self::primary_key(&self.session_token), indexes: keys::Gsi1 { hash: format!("USER#{}", self.user_id), range: format!("SESSION#{}", self.session_token), }, } } } ``` -------------------------------- ### Customizing Entity Type Attribute Name in Modyne Table Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This example demonstrates how to override the default `ENTITY_TYPE_ATTRIBUTE` constant within the `Table` trait implementation. By setting it to a different string like `"et"`, Modyne will use this specified attribute name for storing and retrieving the entity type in DynamoDB items, enabling interoperability with existing table designs. ```Rust use modyne::{keys, Table}; # struct Database { # table_name: String, # client: aws_sdk_dynamodb::Client, # } # impl Table for Database { const ENTITY_TYPE_ATTRIBUTE: &'static str = "et"; type PrimaryKey = keys::Primary; type IndexKeys = keys::Gsi1; fn table_name(&self) -> &str { &self.table_name } fn client(&self) -> &aws_sdk_dynamodb::Client { &self.client } } ``` -------------------------------- ### Implementing UserInfo Query and Aggregation with Modyne Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This snippet demonstrates how to define a custom `QueryInput` for retrieving user information based on `user_id`, and an `Aggregate` structure (`UserInfo`) to merge multiple database items into a single, cohesive data structure. It also shows how to execute the query and reduce the results into the aggregate, illustrating Modyne's pattern for data retrieval and composition. ```Rust # fn primary_key(input: Self::KeyInput<'_>) -> modyne::keys::Primary {unimplemented!()} # fn full_key(&self) -> modyne::keys::FullKey {unimplemented!()} # } use modyne::{ expr, keys, projections, read_projection, Aggregate, Error, Item, QueryInput, QueryInputExt, }; struct UserInfoQuery<'a> { user_id: &'a str, } impl QueryInput for UserInfoQuery<'_> { type Index = keys::Gsi1; type Aggregate = UserInfo; fn key_condition(&self) -> expr::KeyCondition { let partition = format!("USER#{}", self.user_id); expr::KeyCondition::in_partition(partition) } } #[derive(Debug, Default)] struct UserInfo { session_tokens: Vec, metadata: Option, } projections! { enum UserInfoEntities { Session, UserMetadata, } } impl Aggregate for UserInfo { type Projections = UserInfoEntities; fn merge(&mut self, item: Item) -> Result<(), Error> { match read_projection!(item)? { Self::Projections::Session(session) => { self.session_tokens.push(session.session_token) } Self::Projections::UserMetadata(user) => { self.metadata = Some(user) } } Ok(()) } } impl Database { async fn get_user_info_page(&self, user_id: &str) -> Result { let result = UserInfoQuery { user_id: "test" } .query() .execute(self) .await?; let mut info = UserInfo::default(); info.reduce(result.items.unwrap_or_default())?; Ok(info) } } ``` -------------------------------- ### Define Custom Primary and Secondary Keys for DynamoDB in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md Illustrates how to define custom primary and secondary index keys for DynamoDB using `modyne`. These custom key types must be `serde-serializable` and implement `PrimaryKey` or `IndexKey` traits, specifying their hash and range key definitions. ```Rust use modyne::keys::{ GlobalSecondaryIndexDefinition, IndexKey, Key, KeyDefinition, PrimaryKey, PrimaryKeyDefinition, SecondaryIndexDefinition }; #[derive(Debug, serde::Serialize)] struct SessionToken { session_token: String, } impl PrimaryKey for SessionToken { const PRIMARY_KEY_DEFINITION: PrimaryKeyDefinition = PrimaryKeyDefinition { hash_key: "session_token", range_key: None, }; } impl Key for SessionToken { const DEFINITION: KeyDefinition = ::PRIMARY_KEY_DEFINITION.into_key_definition(); } #[derive(Debug, serde::Serialize)] struct UserIndex { user_id: String, } impl IndexKey for UserIndex { const INDEX_DEFINITION: SecondaryIndexDefinition = GlobalSecondaryIndexDefinition { index_name: "user_index", hash_key: "user_id", range_key: None, }.into_index(); } ``` -------------------------------- ### Modyne `Table` Trait API Reference Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This API documentation outlines the `Table` trait in Modyne, which provides an interface for interacting with DynamoDB tables. It includes associated types for primary and index keys, methods for retrieving table name and client, and customizable functions for handling entity type attribute names and their serialization/deserialization. ```APIDOC trait Table { const ENTITY_TYPE_ATTRIBUTE: &'static str = "entity_type"; type PrimaryKey; type IndexKeys; fn table_name(&self) -> &str; fn client(&self) -> &aws_sdk_dynamodb::Client; fn deserialize_entity_type( attr: &AttributeValue, ) -> Result<&EntityTypeNameRef, MalformedEntityTypeError>; fn serialize_entity_type(entity_type: &EntityTypeNameRef) -> AttributeValue; } ``` -------------------------------- ### Renaming Projection Fields with Serde Attributes in Rust Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This Rust snippet demonstrates how to resolve field mismatch errors in Modyne projections by using `serde`'s `#[serde(rename = "...")]` attribute. It allows a field in the projection struct (`session`) to be explicitly mapped to a differently named field in the source entity (`session_token`), ensuring correct deserialization and compilation. ```Rust # use modyne::{EntityDef, Projection}; # struct Database; # impl modyne::Table for Database { # type PrimaryKey = modyne::keys::Primary; # type IndexKeys = modyne::keys::Gsi1; # fn table_name(&self) -> &str {unimplemented!()} # fn client(&self) -> &aws_sdk_dynamodb::Client {unimplemented!()} # } # # impl modyne::Entity for Session { # type KeyInput<'a> = &'a str; # type Table = Database; # type IndexKeys = modyne::keys::Gsi1; # fn primary_key(input: Self::KeyInput<'_>) -> modyne::keys::Primary {unimplemented!()} # fn full_key(&self) -> modyne::keys::FullKey {unimplemented!()} # } # # #[derive(Debug, EntityDef, serde::Serialize, serde::Deserialize)] # struct Session { # user_id: String, # session_token: String, # } # #[derive(Debug, Projection, serde::Deserialize)] #[entity(Session)] struct SessionTokenOnly { #[serde(rename = "session_token")] session: String, } ``` -------------------------------- ### Customizing Entity Type Attribute Value Serialization in Modyne Source: https://github.com/neoeinstein/modyne/blob/main/modyne/docs/modyne.md This snippet illustrates how to customize the serialization and deserialization logic for the entity type attribute by implementing `deserialize_entity_type` and `serialize_entity_type` methods of the `Table` trait. This allows the entity type to be stored in non-standard DynamoDB attribute values, such as a single-element string set, while still using the default `entity_type` attribute name. ```Rust use modyne::{keys, AttributeValue, EntityTypeNameRef, MalformedEntityTypeError, Table}; # struct Database { # table_name: String, # client: aws_sdk_dynamodb::Client, # } # impl Table for Database { type PrimaryKey = keys::Primary; type IndexKeys = keys::Gsi1; fn table_name(&self) -> &str { &self.table_name } fn client(&self) -> &aws_sdk_dynamodb::Client { &self.client } fn deserialize_entity_type( attr: &AttributeValue, ) -> Result<&EntityTypeNameRef, MalformedEntityTypeError> { let values = attr .as_ss() .map_err(|_| MalformedEntityTypeError::Custom("expected a string set".into()))?; let value = values .first() .expect("a DynamoDB string set always has at least one element"); Ok(EntityTypeNameRef::from_str(value.as_str())) } fn serialize_entity_type(entity_type: &EntityTypeNameRef) -> AttributeValue { AttributeValue::Ss(vec![entity_type.to_string()]) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.