{"id":17243561,"url":"https://github.com/gabotechs/dynarust","last_synced_at":"2025-04-14T03:53:34.522Z","repository":{"id":172040026,"uuid":"648771766","full_name":"gabotechs/dynarust","owner":"gabotechs","description":"A DynamoDB odm library for rust","archived":false,"fork":false,"pushed_at":"2025-03-02T11:52:29.000Z","size":37,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-13T11:17:23.941Z","etag":null,"topics":["dynamo","dynamodb","odm","orm","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gabotechs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-02T19:17:53.000Z","updated_at":"2025-03-02T11:52:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"eac02e7e-f95d-46e8-bd87-4598305c23c8","html_url":"https://github.com/gabotechs/dynarust","commit_stats":null,"previous_names":["gabotechs/dynarust"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabotechs%2Fdynarust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabotechs%2Fdynarust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabotechs%2Fdynarust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gabotechs%2Fdynarust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gabotechs","download_url":"https://codeload.github.com/gabotechs/dynarust/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248819365,"owners_count":21166474,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamo","dynamodb","odm","orm","rust"],"created_at":"2024-10-15T06:16:05.580Z","updated_at":"2025-04-14T03:53:34.496Z","avatar_url":"https://github.com/gabotechs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dynarust\n\n[![Coverage Status](https://coveralls.io/repos/github/gabotechs/dynarust/badge.svg?branch=main)](https://coveralls.io/github/gabotechs/dynarust?branch=main)\n\nAn opinionated DynamoDB ODM library for Rust that maps `structs`\nto native Dynamo items using [serde](https://github.com/serde-rs/serde)\nand [serde_json](https://github.com/serde-rs/json).\n\nIt only works with tables with a `HASH` key and a `RANGE` key, referred in\nthe code as `pk` and `sk`. This setup can be useful for a very wide variety\nof use cases.\n\n# Usage\n\nYou will need the following dependencies in your `Cargo.toml` (tweak versions as you need):\n\n```toml\n[dependencies]\ndynarust = \"*\"\nserde = \"*\"\ntokio = { version = \"*\", features = [\"full\"] }\n```\n\n```rust\n// Spawn a local dynamo instance: `docker run -p 8000:8000 amazon/dynamodb-local`\nuse dynarust::serde::{Deserialize, Serialize};\nuse dynarust::serde_json::json;\n\n#[derive(Serialize, Deserialize)]\nstruct Car {\n    brand: String,\n    model: String,\n    horse_power: i64,\n}\n\nimpl dynarust::Resource for Car {\n    fn table() -\u003e String { \"Cars\".into() }\n    fn pk_sk(\u0026self) -\u003e (String, String) { (self.brand.clone(), self.model.clone()) }\n}\n\n#[tokio::main]\nasync fn main() {\n    let client = dynarust::Client::local().await;\n    client.create_table::\u003cCar\u003e(None).await.unwrap();\n\n    let car = Car {\n        brand: \"Tesla\".into(),\n        model: \"Y\".into(),\n        horse_power: 347,\n    };\n\n    client.create(\u0026car).await.unwrap();\n\n    client.update(\u0026car, json!({ \"horse_power\": 534 })).await.unwrap();\n\n    let tesla = client.get::\u003cCar\u003e((\"Tesla\".into(), \"Y\".into())).await.unwrap();\n\n    assert_eq!(tesla.unwrap().horse_power, 534)\n}\n```\n\n# Transactions\n\nDynarust's api is focused on transaction ergonomics, and offers a way or doing transactional operations\nalmost as if they were just normal operations:\n\n```rust\n// Spawn a local dynamo: `docker run -p 8000:8000 amazon/dynamodb-local`\nuse dynarust::serde::{Deserialize, Serialize};\nuse dynarust::serde_json::json;\n\n#[derive(Serialize, Deserialize)]\nstruct Car {\n    brand: String,\n    model: String,\n    n_modifications: i64,\n}\n\nimpl dynarust::Resource for Car {\n    fn table() -\u003e String { \"Cars\".into() }\n    fn pk_sk(\u0026self) -\u003e (String, String) { (self.brand.clone(), self.model.clone()) }\n}\n\n#[derive(Serialize, Deserialize)]\nstruct CarModification {\n    car_brand: String,\n    car_model: String,\n    modification: String,\n    price: f64,\n}\n\nimpl dynarust::Resource for CarModification {\n    fn table() -\u003e String { \"CarModifications\".into() }\n    fn pk_sk(\u0026self) -\u003e (String, String) {(\n        format!(\"{}-{}\", self.car_brand, self.car_model),\n        self.modification.clone(),\n    )}\n}\n\n#[tokio::main]\nasync fn main() {\n    let client = dynarust::Client::local().await;\n    client.create_table::\u003cCar\u003e(None).await.unwrap();\n    client.create_table::\u003cCarModification\u003e(None).await.unwrap();\n\n    let car = Car {\n        brand: \"Tesla\".into(),\n        model: \"Y\".into(),\n        n_modifications: 0,\n    };\n\n    client.create(\u0026car).await.unwrap();\n\n    let car_modification = CarModification {\n        car_brand: \"Tesla\".into(),\n        car_model: \"Y\".into(),\n        modification: \"Loud exhaust\".into(),\n        price: 14999.95,\n    };\n\n    let mut context = dynarust::begin_transaction();\n    dynarust::transact_create(\u0026car_modification, \u0026mut context).unwrap();\n    dynarust::transact_update(\u0026car, json!({ \"n_modifications\": car.n_modifications + 1 }), \u0026mut context).unwrap();\n    client.execute_transaction(context).await.unwrap();\n\n    let tesla = client.get::\u003cCar\u003e((\"Tesla\".into(), \"Y\".into())).await.unwrap();\n\n    assert_eq!(tesla.unwrap().n_modifications, 1)\n}\n```\n\n# Setup\n\nIn order to use this library, the table setup would need to look like this equivalent CFN template:\n```yaml\nDynamoDBTable:\n  Type: AWS::DynamoDB::Table\n  Properties:\n    TableName: my-table\n    AttributeDefinitions:\n      - AttributeName: PrimaryKey\n        AttributeType: S\n      - AttributeName: SecondaryKey\n        AttributeType: S\n    KeySchema:\n      - AttributeName: PrimaryKey\n        KeyType: HASH\n      - AttributeName: SecondaryKey\n        KeyType: RANGE\n```\n\n`dynarust` expects that attributes `PrimaryKey` and `SecondaryKey` are declared in the key schema\nas `HASH` and `RANGE` values, and that both are of type `S` (string).\n\n\n# Coming next\n\n- Support for global secondary indexes, with the same API that exists right now for the\nprimary ones.\n\n# Current Limitations\n\n- Only works with the `HASH` and `RANGE` keys setup.\n- It is not compatible with global or local secondary indexes.\n- Missing some batch operations, right now only `batch_get` is implemented.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabotechs%2Fdynarust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgabotechs%2Fdynarust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgabotechs%2Fdynarust/lists"}