use derive_into::Convert;
#[derive(Debug, PartialEq, Clone)]
struct CustomId(u64);
impl From<u64> for CustomId {
fn from(id: u64) -> Self {
CustomId(id)
}
}
impl From<CustomId> for u64 {
fn from(id: CustomId) -> Self {
id.0
}
}
#[derive(Convert, Debug, PartialEq, Clone)]
#[convert(into(path = "TargetEvent"))]
#[convert(try_from(path = "TargetEvent"))]
enum SourceEvent {
Heartbeat,
Click(u64),
MouseMove(u64, u64),
Login {
username: String,
#[convert(rename = "auth_token")]
token: String,
timestamp: u64,
},
#[convert(rename = "LogoutEvent")]
Logout {
username: String,
timestamp: u64,
},
Message {
from: String,
to: String,
#[convert(unwrap)]
content: Option<String>,
},
UserAction {
user_id: u64,
action_type: SourceActionType,
},
}
#[derive(Debug, PartialEq, Clone)]
enum TargetEvent {
Heartbeat,
Click(CustomId),
MouseMove(CustomId, CustomId),
Login {
username: String,
auth_token: String, timestamp: CustomId,
},
LogoutEvent {
username: String,
timestamp: CustomId,
},
Message {
from: String,
to: String,
content: String, },
UserAction {
user_id: CustomId,
action_type: TargetActionType,
},
}
#[derive(Convert, Debug, PartialEq, Clone)]
#[convert(into(path = "TargetActionType"))]
#[convert(try_from(path = "TargetActionType"))]
enum SourceActionType {
View,
Edit,
Delete,
#[convert(rename = "CreateNew")]
Create,
}
#[derive(Debug, PartialEq, Clone)]
enum TargetActionType {
View,
Edit,
Delete,
CreateNew, }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple_variants() {
let source = SourceEvent::Heartbeat;
let target: TargetEvent = source.into();
assert_eq!(target, TargetEvent::Heartbeat);
let source_again = SourceEvent::try_from(target).unwrap();
assert_eq!(source_again, SourceEvent::Heartbeat);
let source = SourceEvent::Click(42);
let target: TargetEvent = source.into();
assert_eq!(target, TargetEvent::Click(CustomId(42)));
let source_again = SourceEvent::try_from(target).unwrap();
assert_eq!(source_again, SourceEvent::Click(42));
}
#[test]
fn test_multiple_tuple_elements() {
let source = SourceEvent::MouseMove(10, 20);
let target: TargetEvent = source.into();
assert_eq!(target, TargetEvent::MouseMove(CustomId(10), CustomId(20)));
let source_again = SourceEvent::try_from(target).unwrap();
assert_eq!(source_again, SourceEvent::MouseMove(10, 20));
}
#[test]
fn test_struct_variants_with_rename() {
let source = SourceEvent::Login {
username: "user123".to_string(),
token: "abc123".to_string(),
timestamp: 1678901234,
};
let target: TargetEvent = source.clone().into();
match target {
TargetEvent::Login {
username,
auth_token,
timestamp,
} => {
assert_eq!(username, "user123");
assert_eq!(auth_token, "abc123");
assert_eq!(timestamp, CustomId(1678901234));
}
_ => panic!("Unexpected variant"),
}
let source_again = SourceEvent::try_from(target).unwrap();
assert_eq!(source_again, source);
}
#[test]
fn test_renamed_variant() {
let source = SourceEvent::Logout {
username: "user123".to_string(),
timestamp: 1678901235,
};
let target: TargetEvent = source.clone().into();
match target {
TargetEvent::LogoutEvent {
username,
timestamp,
} => {
assert_eq!(username, "user123");
assert_eq!(timestamp, CustomId(1678901235));
}
_ => panic!("Unexpected variant"),
}
let source_again = SourceEvent::try_from(target).unwrap();
assert_eq!(source_again, source);
}
#[test]
fn test_unwrapped_option() {
let source = SourceEvent::Message {
from: "alice".to_string(),
to: "bob".to_string(),
content: Some("Hello!".to_string()),
};
let target: TargetEvent = source.into();
match target {
TargetEvent::Message { from, to, content } => {
assert_eq!(from, "alice");
assert_eq!(to, "bob");
assert_eq!(content, "Hello!");
}
_ => panic!("Unexpected variant"),
}
let source_again = SourceEvent::try_from(target).unwrap();
match source_again {
SourceEvent::Message { from, to, content } => {
assert_eq!(from, "alice");
assert_eq!(to, "bob");
assert_eq!(content, Some("Hello!".to_string()));
}
_ => panic!("Unexpected variant"),
}
}
#[test]
fn test_unwrapped_option_failure() {
let source_with_none = SourceEvent::Message {
from: "alice".to_string(),
to: "bob".to_string(),
content: None,
};
let result: Result<TargetEvent, _> = source_with_none.try_into();
assert!(result.is_err());
}
#[test]
fn test_nested_enum_conversion() {
let source = SourceEvent::UserAction {
user_id: 999,
action_type: SourceActionType::Create,
};
let target: TargetEvent = source.into();
match target {
TargetEvent::UserAction {
user_id,
action_type,
} => {
assert_eq!(user_id, CustomId(999));
assert_eq!(action_type, TargetActionType::CreateNew);
}
_ => panic!("Unexpected variant"),
}
}
}
fn main() {
println!("Running enum conversion tests...");
let source_event = SourceEvent::Login {
username: "test_user".to_string(),
token: "test_token".to_string(),
timestamp: 1234567890,
};
let target_event: TargetEvent = source_event.into();
println!("Converted to target event: {:#?}", target_event);
let source_action = SourceEvent::UserAction {
user_id: 42,
action_type: SourceActionType::Create,
};
let target_action: TargetEvent = source_action.into();
println!("Converted action event: {:#?}", target_action);
}