use derive_into::Convert;
#[derive(Debug, PartialEq, Default)]
struct UserId(u32);
impl From<u32> for UserId {
fn from(id: u32) -> Self {
UserId(id)
}
}
impl From<UserId> for u32 {
fn from(id: UserId) -> Self {
id.0
}
}
#[derive(Debug, PartialEq, Default)]
struct Email(String);
impl From<String> for Email {
fn from(email: String) -> Self {
Email(email)
}
}
impl From<Email> for String {
fn from(email: Email) -> Self {
email.0
}
}
#[derive(Convert, Debug, PartialEq)]
#[convert(into(path = "UserRecord", default))] #[convert(try_from(path = "UserRecord"))] struct User {
name: String,
id: u32,
email: Option<String>,
#[convert(rename = "creation_date")]
created_at: String,
#[convert(unwrap)]
age: Option<u8>,
roles: Vec<String>,
}
#[derive(Debug, Default, PartialEq)]
struct UserRecord {
name: String,
id: UserId, email: Option<Email>, creation_date: String, age: u8, roles: Vec<Email>,
last_login: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_into_conversion() {
let user = User {
name: "John Doe".to_string(),
id: 42,
email: Some("john@example.com".to_string()),
created_at: "2023-01-01".to_string(),
age: Some(30),
roles: vec!["admin".to_string(), "user".to_string()],
};
let record: UserRecord = user.into();
assert_eq!(record.name, "John Doe");
assert_eq!(record.id, UserId(42));
assert_eq!(record.email, Some(Email("john@example.com".to_string())));
assert_eq!(record.creation_date, "2023-01-01");
assert_eq!(record.age, 30);
assert_eq!(record.roles.len(), 2);
assert_eq!(record.roles[0], Email("admin".to_string()));
assert_eq!(record.roles[1], Email("user".to_string()));
assert_eq!(record.last_login, None); }
#[test]
fn test_try_from_conversion() {
let record = UserRecord {
name: "Jane Doe".to_string(),
id: UserId(123),
email: Some(Email("jane@example.com".to_string())),
creation_date: "2023-02-02".to_string(),
age: 25,
roles: vec![Email("moderator".to_string())],
last_login: Some("2023-03-03".to_string()),
};
let user_result = User::try_from(record);
assert!(user_result.is_ok());
let user = user_result.unwrap();
assert_eq!(user.name, "Jane Doe");
assert_eq!(user.id, 123);
assert_eq!(user.email, Some("jane@example.com".to_string()));
assert_eq!(user.created_at, "2023-02-02");
assert_eq!(user.age, Some(25));
assert_eq!(user.roles.len(), 1);
assert_eq!(user.roles[0], "moderator");
}
#[test]
fn test_try_from_failure() {
let record = UserRecord {
name: "Test User".to_string(),
id: UserId(456),
email: None,
creation_date: "2023-04-04".to_string(),
age: 0, roles: vec![],
last_login: None,
};
let user_result = User::try_from(record);
assert!(user_result.is_ok());
}
}
fn main() {
println!("Running struct conversion tests...");
let user = User {
name: "Example User".to_string(),
id: 1,
email: Some("example@test.com".to_string()),
created_at: "2023-05-05".to_string(),
age: Some(42),
roles: vec!["guest".to_string()],
};
let record: UserRecord = user.into();
println!("Converted User to UserRecord: {:#?}", record);
match User::try_from(record) {
Ok(converted_user) => println!("Converted back to User: {:#?}", converted_user),
Err(_) => println!("Conversion failed"),
}
}