7 个版本 (4 个破坏性版本)
0.5.1 | 2024 年 6 月 7 日 |
---|---|
0.5.0 | 2024 年 6 月 6 日 |
0.4.0 | 2024 年 6 月 3 日 |
0.3.1 | 2024 年 5 月 26 日 |
0.1.0 | 2024 年 5 月 18 日 |
#416 in Rust 模式
30KB
309 行
dynamodel
该库提供了一种 derive 宏,用于在您的对象与 HashMap<String, AttributeValue>
之间实现转换。
Derive 宏 Dynamodel
Dynamodel
derive 宏实现了这三个特质,以便更方便地使用 aws-sdk-dynamodb
。
Into<HashMap<String, AttributeValue>>
TryFrom<HashMap<String, AttributeValue>>
AttributeValueConvertible
特质允许实现它的类型在AttributeValue
之间进行转换。
#[derive(Dynamodel)] Convertible
struct YourStruct { ... } <===========> HashMap<String, AttributeValue>
#[derive(Dynamodel)] Convertible
enum YourEnum { ... } <===========> HashMap<String, AttributeValue>
使用 Dynamodel
的要求
要使用 Dynamodel
宏,您的对象的所有字段类型都必须实现 AttributeValueConvertible
特质。
默认情况下,这些类型会自动实现 AttributeValueConvertible
特质,因此在使用这些类型时不需要额外的代码。
类型 | AttributeValue 变体 |
---|---|
String |
AttributeValue::S("...") |
u8, u16, u32, u64, u128, usize i8, i16, i32, i64, i128, isize f32, f64 |
AttributeValue::N("...") |
bool |
AttributeValue::Bool(...) |
Vec 的任何实现 AttributeValueConvertible 特质的类型 |
AttributeValue::L([...]) |
实现了 Dynamodel 宏的任何类型 |
AttributeValue::M({ ... }) |
上表最后一行显示,一旦您将 Dynamodel
宏应用于您的对象,它也为您对象实现了 AttributeValueConvertible
特质。
因此,您可以创建应用了 Dynamodel
宏的嵌套对象结构。
如果您想使用其他类型,则需要为您类型实现 AttributeValueConvertible
特质。
使用
use dynamodel::Dynamodel;
use std::collections::HashMap;
use aws_sdk_dynamodb::types::AttributeValue;
#[derive(Dynamodel, Debug, Clone, PartialEq)]
struct Person {
first_name: String,
last_name: String,
age: u8,
}
let person = Person {
first_name: "Kanji".into(),
last_name: "Tanaka".into(),
age: 23,
};
let item: HashMap<String, AttributeValue> = [
("first_name".to_string(), AttributeValue::S("Kanji".into())),
("last_name".to_string(), AttributeValue::S("Tanaka".into())),
("age".to_string(), AttributeValue::N("23".into()))
].into();
// Convert from Person into HashMap<String, AttributeValue>.
let converted: HashMap<String, AttributeValue> = person.clone().into();
assert_eq!(converted, item);
// Convert from HashMap<String, AttributeValue> into Person.
// This conversion uses std::convert::TryFrom trait, so this returns a Result.
let converted: Person = item.try_into().unwrap();
assert_eq!(converted, person);
修改默认行为
如同 Serde
包一样,您可以通过此类属性修改默认行为。
use dynamodel::{Dynamodel, ConvertError};
use std::collections::HashMap;
use aws_sdk_dynamodb::{types::AttributeValue, primitives::Blob};
// Vec<u8> is converted to AttributeValue::L by default,
// but this case, the `data` field is converted to AttributeValue::B.
#[derive(Dynamodel)]
struct BinaryData {
#[dynamodel(into = "to_blob", try_from = "from_blob")]
data: Vec<u8>
}
fn to_blob(value: Vec<u8>) -> AttributeValue {
AttributeValue::B(Blob::new(value))
}
fn from_blob(value: &AttributeValue) -> Result<Vec<u8>, ConvertError> {
value.as_b()
.map(|b| b.clone().into_inner())
.map_err(|err| ConvertError::AttributeValueUnmatched("B".to_string(), err.clone()))
}
函数定义必须满足以下条件。
字段属性 | 参数 | 返回值 |
---|---|---|
#[dynamodel(进入= "...")] |
字段类型 |
AttributeValue |
#[dynamodel(try_from= "...")] |
&AttributeValue |
结果<字段类型,转换错误> |
示例
单表设计
以下图示显示,Video
和VideoStats
都存储在同一张表中。
#[derive(Dynamodel)]
#[dynamodel(extra = "VideoStats::sort_key", rename_all = "PascalCase")]
struct VideoStats {
#[dynamodel(rename = "PK")]
id: String,
view_count: u64,
}
impl VideoStats {
fn sort_key(&self) -> HashMap<String, AttributeValue> {
[
("SK".to_string(), AttributeValue::S("VideoStats".into())),
].into()
}
}
假设您想添加一个可按时间戳排序的VideoComment
对象,如下所示。
#[derive(Dynamodel)]
#[dynamodel(rename_all = "PascalCase")]
struct VideoComment {
#[dynamodel(rename = "PK")]
id: String,
#[dynamodel(rename = "SK", into = "sort_key", try_from = "get_timestamp")]
timestamp: String,
content: String,
}
fn sort_key(timestamp: String) -> AttributeValue {
AttributeValue::S(format!("VideoComment#{timestamp}"))
}
fn get_timestamp(value: &AttributeValue) -> Result<String, ConvertError> {
value.as_s()
.map(|v| v.split('#').last().unwrap().to_string())
.map_err(|e| ConvertError::AttributeValueUnmatched("S".into(), e.clone()))
}
更多功能
更多功能,请参阅此维基。
许可证
此软件根据MIT许可证发布。
依赖项
~17MB
~272K SLoC