1use derive_builder::Builder;
2use edit_xml::{Document, Element};
3use serde::{Deserialize, Serialize};
4
5use crate::editor::{
6 utils::{add_if_present, from_element_using_builder, sync_element},
7 ChildOfListElement, ComparableElement, ElementConverter, HasElementName, UpdatableElement,
8 XMLEditorError,
9};
10
11#[derive(Debug, Serialize, Deserialize, Clone, Default)]
12pub struct Developers {
13 pub developer: Vec<Developer>,
14}
15
16#[derive(Debug, Clone, Default, PartialEq, Eq, Builder, Serialize, Deserialize)]
17pub struct Developer {
18 #[builder(setter(into, strip_option), default)]
19 pub id: Option<String>,
20 #[builder(setter(into, strip_option), default)]
21 pub name: Option<String>,
22 #[builder(setter(into, strip_option), default)]
23 pub email: Option<String>,
24 #[builder(setter(into, strip_option), default)]
25 pub url: Option<String>,
26 #[builder(setter(into, strip_option), default)]
27 pub organization: Option<String>,
28 #[builder(setter(into, strip_option), default)]
29 pub organization_url: Option<String>,
30 #[builder(setter(into, strip_option), default)]
31 pub timezone: Option<String>,
32 }
34impl Developer {
35 pub fn is_same_developer(&self, other: &Developer) -> bool {
39 self.id == other.id
40 }
41}
42
43impl HasElementName for Developer {
44 fn element_name() -> &'static str {
45 "developer"
46 }
47}
48impl ElementConverter for Developer {
49 from_element_using_builder!(
50 DeveloperBuilder,
51 element,
52 document,
53 "id" => id,
54 "name" => name,
55 "email" => email,
56 "url" => url,
57 "organization" => organization,
58 "organizationUrl" => organization_url,
59 "timezone" => timezone
60 );
61
62 fn into_children(
63 self,
64 document: &mut edit_xml::Document,
65 ) -> Result<Vec<edit_xml::Element>, crate::editor::XMLEditorError> {
66 let Self {
67 id,
68 name,
69 email,
70 url,
71 organization,
72 organization_url,
73 timezone,
74 } = self;
75 let mut children = vec![];
76 add_if_present!(document, children, id, "id");
77 add_if_present!(document, children, name, "name");
78 add_if_present!(document, children, email, "email");
79 add_if_present!(document, children, url, "url");
80 add_if_present!(document, children, organization, "organization");
81 add_if_present!(document, children, organization_url, "organizationUrl");
82 add_if_present!(document, children, timezone, "timezone");
83 Ok(children)
84 }
85}
86impl ChildOfListElement for Developer {
87 fn parent_element_name() -> &'static str {
88 "developers"
89 }
90}
91impl ComparableElement for Developer {
92 fn is_same_item(&self, other: &Self) -> bool {
93 self.is_same_developer(other)
94 }
95}
96impl UpdatableElement for Developer {
97 fn update_element(
98 &self,
99 element: Element,
100 document: &mut Document,
101 ) -> Result<(), XMLEditorError> {
102 sync_element(document, element, "id", self.id.clone());
103 sync_element(document, element, "name", self.name.clone());
104 sync_element(document, element, "email", self.email.clone());
105 sync_element(document, element, "url", self.url.clone());
106 sync_element(document, element, "organization", self.organization.clone());
107 sync_element(
108 document,
109 element,
110 "organizationUrl",
111 self.organization_url.clone(),
112 );
113 sync_element(document, element, "timezone", self.timezone.clone());
114
115 Ok(())
116 }
117}
118#[cfg(test)]
119mod tests {
120 use crate::editor::utils::test_utils;
121
122 use super::Developer;
123
124 fn test_parse_methods(value: &str, expected: Developer) -> anyhow::Result<()> {
125 let dev_via_edit_xml = test_utils::create_xml_to_element::<Developer>(value)?;
126 let dev_via_serde: Developer = quick_xml::de::from_str(value)?;
127
128 assert_eq!(dev_via_edit_xml, expected);
129 assert_eq!(dev_via_serde, expected);
130 println!("{:#?}", dev_via_edit_xml);
131
132 let dep_serialize_serde = quick_xml::se::to_string(&expected)?;
133 println!("Serialized Over Serde \n {}", dep_serialize_serde);
134 Ok(())
135 }
136
137 #[test]
138 pub fn test_element_parse() -> anyhow::Result<()> {
139 let test_value = r#"
140 <developer>
141 <id>wyatt-herkamp</id>
142 <name>Wyatt Herkamp</name>
143 <email>test@wyatt-herkamp.dev</email>
144 <url>https://wyatt-herkamp.dev</url>
145 </developer>
146 "#;
147 let dev = Developer {
148 id: Some("wyatt-herkamp".to_string()),
149 name: Some("Wyatt Herkamp".to_string()),
150 email: Some("test@wyatt-herkamp.dev".to_owned()),
151 url: Some("https://wyatt-herkamp.dev".to_owned()),
152
153 ..Default::default()
154 };
155 test_parse_methods(test_value, dev)
156 }
157}