Skip to main content

serde_xpath/
de.rs

1use roxmltree::Node;
2use serde::de::Visitor;
3use serde::de::{self};
4
5use crate::error::Error;
6use crate::xpath::XPath;
7use crate::xpath::XPathResult;
8
9pub struct XPathDeserializer<'a, 'input> {
10    node: Node<'a, 'input>,
11}
12
13impl<'a, 'input> XPathDeserializer<'a, 'input> {
14    pub fn new(node: Node<'a, 'input>) -> Self {
15        XPathDeserializer { node }
16    }
17
18    pub fn from_node(node: Node<'a, 'input>) -> Self {
19        Self::new(node)
20    }
21}
22
23impl<'de, 'a, 'input> de::Deserializer<'de> for XPathDeserializer<'a, 'input> {
24    type Error = Error;
25
26    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
27    where
28        V: Visitor<'de>,
29    {
30        // Default to string for any
31        if let Some(text) = self.node.text() {
32            visitor.visit_string(text.to_string())
33        } else {
34            visitor.visit_string(String::new())
35        }
36    }
37
38    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
39    where
40        V: Visitor<'de>,
41    {
42        let text = self.node.text().unwrap_or("");
43        let b = text
44            .parse::<bool>()
45            .map_err(|_| Error::Custom(format!("invalid bool: {}", text)))?;
46        visitor.visit_bool(b)
47    }
48
49    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
50    where
51        V: Visitor<'de>,
52    {
53        let text = self.node.text().unwrap_or("");
54        let n = text
55            .parse::<i8>()
56            .map_err(|_| Error::Custom(format!("invalid i8: {}", text)))?;
57        visitor.visit_i8(n)
58    }
59
60    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
61    where
62        V: Visitor<'de>,
63    {
64        let text = self.node.text().unwrap_or("");
65        let n = text
66            .parse::<i16>()
67            .map_err(|_| Error::Custom(format!("invalid i16: {}", text)))?;
68        visitor.visit_i16(n)
69    }
70
71    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
72    where
73        V: Visitor<'de>,
74    {
75        let text = self.node.text().unwrap_or("");
76        let n = text
77            .parse::<i32>()
78            .map_err(|_| Error::Custom(format!("invalid i32: {}", text)))?;
79        visitor.visit_i32(n)
80    }
81
82    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
83    where
84        V: Visitor<'de>,
85    {
86        let text = self.node.text().unwrap_or("");
87        let n = text
88            .parse::<i64>()
89            .map_err(|_| Error::Custom(format!("invalid i64: {}", text)))?;
90        visitor.visit_i64(n)
91    }
92
93    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
94    where
95        V: Visitor<'de>,
96    {
97        let text = self.node.text().unwrap_or("");
98        let n = text
99            .parse::<u8>()
100            .map_err(|_| Error::Custom(format!("invalid u8: {}", text)))?;
101        visitor.visit_u8(n)
102    }
103
104    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
105    where
106        V: Visitor<'de>,
107    {
108        let text = self.node.text().unwrap_or("");
109        let n = text
110            .parse::<u16>()
111            .map_err(|_| Error::Custom(format!("invalid u16: {}", text)))?;
112        visitor.visit_u16(n)
113    }
114
115    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
116    where
117        V: Visitor<'de>,
118    {
119        let text = self.node.text().unwrap_or("");
120        let n = text
121            .parse::<u32>()
122            .map_err(|_| Error::Custom(format!("invalid u32: {}", text)))?;
123        visitor.visit_u32(n)
124    }
125
126    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
127    where
128        V: Visitor<'de>,
129    {
130        let text = self.node.text().unwrap_or("");
131        let n = text
132            .parse::<u64>()
133            .map_err(|_| Error::Custom(format!("invalid u64: {}", text)))?;
134        visitor.visit_u64(n)
135    }
136
137    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
138    where
139        V: Visitor<'de>,
140    {
141        let text = self.node.text().unwrap_or("");
142        let n = text
143            .parse::<f32>()
144            .map_err(|_| Error::Custom(format!("invalid f32: {}", text)))?;
145        visitor.visit_f32(n)
146    }
147
148    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
149    where
150        V: Visitor<'de>,
151    {
152        let text = self.node.text().unwrap_or("");
153        let n = text
154            .parse::<f64>()
155            .map_err(|_| Error::Custom(format!("invalid f64: {}", text)))?;
156        visitor.visit_f64(n)
157    }
158
159    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
160    where
161        V: Visitor<'de>,
162    {
163        let text = self.node.text().unwrap_or("");
164        let c = text.chars().next().ok_or_else(|| {
165            Error::Custom("empty string for char".to_string())
166        })?;
167        visitor.visit_char(c)
168    }
169
170    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
171    where
172        V: Visitor<'de>,
173    {
174        let text = self.node.text().unwrap_or("");
175        visitor.visit_string(text.to_string())
176    }
177
178    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
179    where
180        V: Visitor<'de>,
181    {
182        let text = self.node.text().unwrap_or("");
183        visitor.visit_string(text.to_string())
184    }
185
186    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
187    where
188        V: Visitor<'de>,
189    {
190        Err(Error::Custom("bytes not supported".to_string()))
191    }
192
193    fn deserialize_byte_buf<V>(
194        self,
195        _visitor: V,
196    ) -> Result<V::Value, Self::Error>
197    where
198        V: Visitor<'de>,
199    {
200        Err(Error::Custom("byte_buf not supported".to_string()))
201    }
202
203    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
204    where
205        V: Visitor<'de>,
206    {
207        visitor.visit_some(self)
208    }
209
210    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
211    where
212        V: Visitor<'de>,
213    {
214        visitor.visit_unit()
215    }
216
217    fn deserialize_unit_struct<V>(
218        self,
219        _name: &'static str,
220        visitor: V,
221    ) -> Result<V::Value, Self::Error>
222    where
223        V: Visitor<'de>,
224    {
225        visitor.visit_unit()
226    }
227
228    fn deserialize_newtype_struct<V>(
229        self,
230        _name: &'static str,
231        visitor: V,
232    ) -> Result<V::Value, Self::Error>
233    where
234        V: Visitor<'de>,
235    {
236        visitor.visit_newtype_struct(self)
237    }
238
239    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
240    where
241        V: Visitor<'de>,
242    {
243        Err(Error::Custom(
244            "seq deserialization requires xpath context".to_string(),
245        ))
246    }
247
248    fn deserialize_tuple<V>(
249        self,
250        _len: usize,
251        _visitor: V,
252    ) -> Result<V::Value, Self::Error>
253    where
254        V: Visitor<'de>,
255    {
256        Err(Error::Custom("tuple not supported".to_string()))
257    }
258
259    fn deserialize_tuple_struct<V>(
260        self,
261        _name: &'static str,
262        _len: usize,
263        _visitor: V,
264    ) -> Result<V::Value, Self::Error>
265    where
266        V: Visitor<'de>,
267    {
268        Err(Error::Custom("tuple struct not supported".to_string()))
269    }
270
271    fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
272    where
273        V: Visitor<'de>,
274    {
275        Err(Error::Custom("map not supported".to_string()))
276    }
277
278    fn deserialize_struct<V>(
279        self,
280        _name: &'static str,
281        _fields: &'static [&'static str],
282        _visitor: V,
283    ) -> Result<V::Value, Self::Error>
284    where
285        V: Visitor<'de>,
286    {
287        Err(Error::Custom(
288            "struct deserialization requires xpath descriptors".to_string(),
289        ))
290    }
291
292    fn deserialize_enum<V>(
293        self,
294        _name: &'static str,
295        _variants: &'static [&'static str],
296        _visitor: V,
297    ) -> Result<V::Value, Self::Error>
298    where
299        V: Visitor<'de>,
300    {
301        Err(Error::Custom("enum not supported".to_string()))
302    }
303
304    fn deserialize_identifier<V>(
305        self,
306        visitor: V,
307    ) -> Result<V::Value, Self::Error>
308    where
309        V: Visitor<'de>,
310    {
311        self.deserialize_string(visitor)
312    }
313
314    fn deserialize_ignored_any<V>(
315        self,
316        visitor: V,
317    ) -> Result<V::Value, Self::Error>
318    where
319        V: Visitor<'de>,
320    {
321        visitor.visit_unit()
322    }
323}
324
325// Deserializer for attribute values
326pub struct AttributeDeserializer<'a> {
327    value: &'a str,
328}
329
330impl<'a> AttributeDeserializer<'a> {
331    pub fn new(value: &'a str) -> Self {
332        AttributeDeserializer { value }
333    }
334}
335
336impl<'de, 'a> de::Deserializer<'de> for AttributeDeserializer<'a> {
337    type Error = Error;
338
339    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
340    where
341        V: Visitor<'de>,
342    {
343        visitor.visit_string(self.value.to_string())
344    }
345
346    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
347    where
348        V: Visitor<'de>,
349    {
350        let b = self.value.parse::<bool>().map_err(|_| {
351            Error::Custom(format!("invalid bool: {}", self.value))
352        })?;
353        visitor.visit_bool(b)
354    }
355
356    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
357    where
358        V: Visitor<'de>,
359    {
360        let n = self.value.parse::<i8>().map_err(|_| {
361            Error::Custom(format!("invalid i8: {}", self.value))
362        })?;
363        visitor.visit_i8(n)
364    }
365
366    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
367    where
368        V: Visitor<'de>,
369    {
370        let n = self.value.parse::<i16>().map_err(|_| {
371            Error::Custom(format!("invalid i16: {}", self.value))
372        })?;
373        visitor.visit_i16(n)
374    }
375
376    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
377    where
378        V: Visitor<'de>,
379    {
380        let n = self.value.parse::<i32>().map_err(|_| {
381            Error::Custom(format!("invalid i32: {}", self.value))
382        })?;
383        visitor.visit_i32(n)
384    }
385
386    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
387    where
388        V: Visitor<'de>,
389    {
390        let n = self.value.parse::<i64>().map_err(|_| {
391            Error::Custom(format!("invalid i64: {}", self.value))
392        })?;
393        visitor.visit_i64(n)
394    }
395
396    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
397    where
398        V: Visitor<'de>,
399    {
400        let n = self.value.parse::<u8>().map_err(|_| {
401            Error::Custom(format!("invalid u8: {}", self.value))
402        })?;
403        visitor.visit_u8(n)
404    }
405
406    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
407    where
408        V: Visitor<'de>,
409    {
410        let n = self.value.parse::<u16>().map_err(|_| {
411            Error::Custom(format!("invalid u16: {}", self.value))
412        })?;
413        visitor.visit_u16(n)
414    }
415
416    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
417    where
418        V: Visitor<'de>,
419    {
420        let n = self.value.parse::<u32>().map_err(|_| {
421            Error::Custom(format!("invalid u32: {}", self.value))
422        })?;
423        visitor.visit_u32(n)
424    }
425
426    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
427    where
428        V: Visitor<'de>,
429    {
430        let n = self.value.parse::<u64>().map_err(|_| {
431            Error::Custom(format!("invalid u64: {}", self.value))
432        })?;
433        visitor.visit_u64(n)
434    }
435
436    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
437    where
438        V: Visitor<'de>,
439    {
440        let n = self.value.parse::<f32>().map_err(|_| {
441            Error::Custom(format!("invalid f32: {}", self.value))
442        })?;
443        visitor.visit_f32(n)
444    }
445
446    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
447    where
448        V: Visitor<'de>,
449    {
450        let n = self.value.parse::<f64>().map_err(|_| {
451            Error::Custom(format!("invalid f64: {}", self.value))
452        })?;
453        visitor.visit_f64(n)
454    }
455
456    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
457    where
458        V: Visitor<'de>,
459    {
460        let c = self.value.chars().next().ok_or_else(|| {
461            Error::Custom("empty string for char".to_string())
462        })?;
463        visitor.visit_char(c)
464    }
465
466    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
467    where
468        V: Visitor<'de>,
469    {
470        visitor.visit_string(self.value.to_string())
471    }
472
473    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
474    where
475        V: Visitor<'de>,
476    {
477        visitor.visit_string(self.value.to_string())
478    }
479
480    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
481    where
482        V: Visitor<'de>,
483    {
484        Err(Error::Custom("bytes not supported".to_string()))
485    }
486
487    fn deserialize_byte_buf<V>(
488        self,
489        _visitor: V,
490    ) -> Result<V::Value, Self::Error>
491    where
492        V: Visitor<'de>,
493    {
494        Err(Error::Custom("byte_buf not supported".to_string()))
495    }
496
497    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
498    where
499        V: Visitor<'de>,
500    {
501        visitor.visit_some(self)
502    }
503
504    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
505    where
506        V: Visitor<'de>,
507    {
508        visitor.visit_unit()
509    }
510
511    fn deserialize_unit_struct<V>(
512        self,
513        _name: &'static str,
514        visitor: V,
515    ) -> Result<V::Value, Self::Error>
516    where
517        V: Visitor<'de>,
518    {
519        visitor.visit_unit()
520    }
521
522    fn deserialize_newtype_struct<V>(
523        self,
524        _name: &'static str,
525        visitor: V,
526    ) -> Result<V::Value, Self::Error>
527    where
528        V: Visitor<'de>,
529    {
530        visitor.visit_newtype_struct(self)
531    }
532
533    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
534    where
535        V: Visitor<'de>,
536    {
537        Err(Error::Custom("seq not supported for attributes".to_string()))
538    }
539
540    fn deserialize_tuple<V>(
541        self,
542        _len: usize,
543        _visitor: V,
544    ) -> Result<V::Value, Self::Error>
545    where
546        V: Visitor<'de>,
547    {
548        Err(Error::Custom("tuple not supported".to_string()))
549    }
550
551    fn deserialize_tuple_struct<V>(
552        self,
553        _name: &'static str,
554        _len: usize,
555        _visitor: V,
556    ) -> Result<V::Value, Self::Error>
557    where
558        V: Visitor<'de>,
559    {
560        Err(Error::Custom("tuple struct not supported".to_string()))
561    }
562
563    fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
564    where
565        V: Visitor<'de>,
566    {
567        Err(Error::Custom("map not supported".to_string()))
568    }
569
570    fn deserialize_struct<V>(
571        self,
572        _name: &'static str,
573        _fields: &'static [&'static str],
574        _visitor: V,
575    ) -> Result<V::Value, Self::Error>
576    where
577        V: Visitor<'de>,
578    {
579        Err(Error::Custom("struct not supported for attributes".to_string()))
580    }
581
582    fn deserialize_enum<V>(
583        self,
584        _name: &'static str,
585        _variants: &'static [&'static str],
586        _visitor: V,
587    ) -> Result<V::Value, Self::Error>
588    where
589        V: Visitor<'de>,
590    {
591        Err(Error::Custom("enum not supported".to_string()))
592    }
593
594    fn deserialize_identifier<V>(
595        self,
596        visitor: V,
597    ) -> Result<V::Value, Self::Error>
598    where
599        V: Visitor<'de>,
600    {
601        self.deserialize_string(visitor)
602    }
603
604    fn deserialize_ignored_any<V>(
605        self,
606        visitor: V,
607    ) -> Result<V::Value, Self::Error>
608    where
609        V: Visitor<'de>,
610    {
611        visitor.visit_unit()
612    }
613}
614
615// Deserializer for text content
616pub struct TextDeserializer<'a> {
617    text: &'a str,
618}
619
620impl<'a> TextDeserializer<'a> {
621    pub fn new(text: &'a str) -> Self {
622        TextDeserializer { text }
623    }
624}
625
626impl<'de, 'a> de::Deserializer<'de> for TextDeserializer<'a> {
627    type Error = Error;
628
629    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
630    where
631        V: Visitor<'de>,
632    {
633        visitor.visit_string(self.text.to_string())
634    }
635
636    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
637    where
638        V: Visitor<'de>,
639    {
640        let b = self.text.parse::<bool>().map_err(|_| {
641            Error::Custom(format!("invalid bool: {}", self.text))
642        })?;
643        visitor.visit_bool(b)
644    }
645
646    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
647    where
648        V: Visitor<'de>,
649    {
650        let n = self
651            .text
652            .parse::<i8>()
653            .map_err(|_| Error::Custom(format!("invalid i8: {}", self.text)))?;
654        visitor.visit_i8(n)
655    }
656
657    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
658    where
659        V: Visitor<'de>,
660    {
661        let n = self.text.parse::<i16>().map_err(|_| {
662            Error::Custom(format!("invalid i16: {}", self.text))
663        })?;
664        visitor.visit_i16(n)
665    }
666
667    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
668    where
669        V: Visitor<'de>,
670    {
671        let n = self.text.parse::<i32>().map_err(|_| {
672            Error::Custom(format!("invalid i32: {}", self.text))
673        })?;
674        visitor.visit_i32(n)
675    }
676
677    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
678    where
679        V: Visitor<'de>,
680    {
681        let n = self.text.parse::<i64>().map_err(|_| {
682            Error::Custom(format!("invalid i64: {}", self.text))
683        })?;
684        visitor.visit_i64(n)
685    }
686
687    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
688    where
689        V: Visitor<'de>,
690    {
691        let n = self
692            .text
693            .parse::<u8>()
694            .map_err(|_| Error::Custom(format!("invalid u8: {}", self.text)))?;
695        visitor.visit_u8(n)
696    }
697
698    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
699    where
700        V: Visitor<'de>,
701    {
702        let n = self.text.parse::<u16>().map_err(|_| {
703            Error::Custom(format!("invalid u16: {}", self.text))
704        })?;
705        visitor.visit_u16(n)
706    }
707
708    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
709    where
710        V: Visitor<'de>,
711    {
712        let n = self.text.parse::<u32>().map_err(|_| {
713            Error::Custom(format!("invalid u32: {}", self.text))
714        })?;
715        visitor.visit_u32(n)
716    }
717
718    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
719    where
720        V: Visitor<'de>,
721    {
722        let n = self.text.parse::<u64>().map_err(|_| {
723            Error::Custom(format!("invalid u64: {}", self.text))
724        })?;
725        visitor.visit_u64(n)
726    }
727
728    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
729    where
730        V: Visitor<'de>,
731    {
732        let n = self.text.parse::<f32>().map_err(|_| {
733            Error::Custom(format!("invalid f32: {}", self.text))
734        })?;
735        visitor.visit_f32(n)
736    }
737
738    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
739    where
740        V: Visitor<'de>,
741    {
742        let n = self.text.parse::<f64>().map_err(|_| {
743            Error::Custom(format!("invalid f64: {}", self.text))
744        })?;
745        visitor.visit_f64(n)
746    }
747
748    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
749    where
750        V: Visitor<'de>,
751    {
752        let c = self.text.chars().next().ok_or_else(|| {
753            Error::Custom("empty string for char".to_string())
754        })?;
755        visitor.visit_char(c)
756    }
757
758    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
759    where
760        V: Visitor<'de>,
761    {
762        visitor.visit_string(self.text.to_string())
763    }
764
765    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
766    where
767        V: Visitor<'de>,
768    {
769        visitor.visit_string(self.text.to_string())
770    }
771
772    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
773    where
774        V: Visitor<'de>,
775    {
776        Err(Error::Custom("bytes not supported".to_string()))
777    }
778
779    fn deserialize_byte_buf<V>(
780        self,
781        _visitor: V,
782    ) -> Result<V::Value, Self::Error>
783    where
784        V: Visitor<'de>,
785    {
786        Err(Error::Custom("byte_buf not supported".to_string()))
787    }
788
789    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
790    where
791        V: Visitor<'de>,
792    {
793        visitor.visit_some(self)
794    }
795
796    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
797    where
798        V: Visitor<'de>,
799    {
800        visitor.visit_unit()
801    }
802
803    fn deserialize_unit_struct<V>(
804        self,
805        _name: &'static str,
806        visitor: V,
807    ) -> Result<V::Value, Self::Error>
808    where
809        V: Visitor<'de>,
810    {
811        visitor.visit_unit()
812    }
813
814    fn deserialize_newtype_struct<V>(
815        self,
816        _name: &'static str,
817        visitor: V,
818    ) -> Result<V::Value, Self::Error>
819    where
820        V: Visitor<'de>,
821    {
822        visitor.visit_newtype_struct(self)
823    }
824
825    fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
826    where
827        V: Visitor<'de>,
828    {
829        Err(Error::Custom("seq not supported for text".to_string()))
830    }
831
832    fn deserialize_tuple<V>(
833        self,
834        _len: usize,
835        _visitor: V,
836    ) -> Result<V::Value, Self::Error>
837    where
838        V: Visitor<'de>,
839    {
840        Err(Error::Custom("tuple not supported".to_string()))
841    }
842
843    fn deserialize_tuple_struct<V>(
844        self,
845        _name: &'static str,
846        _len: usize,
847        _visitor: V,
848    ) -> Result<V::Value, Self::Error>
849    where
850        V: Visitor<'de>,
851    {
852        Err(Error::Custom("tuple struct not supported".to_string()))
853    }
854
855    fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
856    where
857        V: Visitor<'de>,
858    {
859        Err(Error::Custom("map not supported".to_string()))
860    }
861
862    fn deserialize_struct<V>(
863        self,
864        _name: &'static str,
865        _fields: &'static [&'static str],
866        _visitor: V,
867    ) -> Result<V::Value, Self::Error>
868    where
869        V: Visitor<'de>,
870    {
871        Err(Error::Custom("struct not supported for text".to_string()))
872    }
873
874    fn deserialize_enum<V>(
875        self,
876        _name: &'static str,
877        _variants: &'static [&'static str],
878        _visitor: V,
879    ) -> Result<V::Value, Self::Error>
880    where
881        V: Visitor<'de>,
882    {
883        Err(Error::Custom("enum not supported".to_string()))
884    }
885
886    fn deserialize_identifier<V>(
887        self,
888        visitor: V,
889    ) -> Result<V::Value, Self::Error>
890    where
891        V: Visitor<'de>,
892    {
893        self.deserialize_string(visitor)
894    }
895
896    fn deserialize_ignored_any<V>(
897        self,
898        visitor: V,
899    ) -> Result<V::Value, Self::Error>
900    where
901        V: Visitor<'de>,
902    {
903        visitor.visit_unit()
904    }
905}
906
907// Private module for struct descriptors
908pub mod __private {
909    use super::*;
910
911    #[derive(Debug, Clone, Copy)]
912    pub enum FieldKind {
913        Element,
914        Text,
915        Attribute,
916        Sequence,
917        Optional,
918        OptionalSequence,
919    }
920
921    #[derive(Debug, Clone, Copy)]
922    pub struct FieldDescriptor {
923        pub name: &'static str,
924        pub xpath: &'static str,
925        pub kind: FieldKind,
926    }
927
928    #[derive(Debug, Clone, Copy)]
929    pub struct StructDescriptor {
930        pub name: &'static str,
931        pub root_xpath: &'static str,
932        pub fields: &'static [FieldDescriptor],
933    }
934
935    pub fn deserialize_xpath_struct<T, F>(
936        xml: &str,
937        descriptor: &StructDescriptor,
938        field_deserializer: F,
939    ) -> Result<T, Error>
940    where
941        F: FnOnce(StructFieldDeserializer<'_, '_>) -> Result<T, Error>,
942    {
943        let doc = roxmltree::Document::parse(xml)?;
944        let root = doc.root_element();
945
946        // Find the root node using the struct's xpath
947        let root_xpath =
948            XPath::parse(descriptor.root_xpath).map_err(Error::XPath)?;
949
950        let target_node = root_xpath
951            .evaluate_single(root)
952            .and_then(|r| r.as_node())
953            .ok_or_else(|| {
954                Error::XPath(format!(
955                    "root xpath '{}' not found",
956                    descriptor.root_xpath
957                ))
958            })?;
959
960        let deser = StructFieldDeserializer { node: target_node, descriptor };
961
962        field_deserializer(deser)
963    }
964
965    pub struct StructFieldDeserializer<'a, 'input> {
966        pub node: Node<'a, 'input>,
967        pub descriptor: &'a StructDescriptor,
968    }
969
970    impl<'a, 'input> StructFieldDeserializer<'a, 'input> {
971        pub fn deserialize_field<'de, T: serde::Deserialize<'de>>(
972            &self,
973            field_name: &str,
974        ) -> Result<T, Error> {
975            let field = self
976                .descriptor
977                .fields
978                .iter()
979                .find(|f| f.name == field_name)
980                .ok_or_else(|| Error::MissingField(field_name.to_string()))?;
981
982            let xpath = XPath::parse(field.xpath).map_err(Error::XPath)?;
983
984            match field.kind {
985                FieldKind::Attribute => {
986                    let result =
987                        xpath.evaluate_single(self.node).ok_or_else(|| {
988                            Error::MissingField(field_name.to_string())
989                        })?;
990
991                    let value = result.as_str().ok_or_else(|| {
992                        Error::XPath(format!(
993                            "expected attribute for field '{}'",
994                            field_name
995                        ))
996                    })?;
997
998                    T::deserialize(AttributeDeserializer::new(value))
999                }
1000                FieldKind::Text => {
1001                    let result =
1002                        xpath.evaluate_single(self.node).ok_or_else(|| {
1003                            Error::MissingField(field_name.to_string())
1004                        })?;
1005
1006                    let text = result.text().ok_or_else(|| {
1007                        Error::XPath(format!(
1008                            "no text content for field '{}'",
1009                            field_name
1010                        ))
1011                    })?;
1012
1013                    T::deserialize(TextDeserializer::new(text))
1014                }
1015                FieldKind::Element => {
1016                    let result =
1017                        xpath.evaluate_single(self.node).ok_or_else(|| {
1018                            Error::MissingField(field_name.to_string())
1019                        })?;
1020
1021                    let node = result.as_node().ok_or_else(|| {
1022                        Error::XPath(format!(
1023                            "expected element for field '{}'",
1024                            field_name
1025                        ))
1026                    })?;
1027
1028                    T::deserialize(XPathDeserializer::new(node))
1029                }
1030                FieldKind::Optional => {
1031                    // Return None if xpath doesn't match
1032                    match xpath.evaluate_single(self.node) {
1033                        Some(_) => {
1034                            // The Option<T> will be deserialized, we need to
1035                            // handle this carefully
1036                            // For now, just propagate
1037                            self.deserialize_field_inner::<T>(field)
1038                        }
1039                        None => {
1040                            // Return default (None for Option)
1041                            T::deserialize(OptionNoneDeserializer)
1042                        }
1043                    }
1044                }
1045                FieldKind::Sequence => {
1046                    let results = xpath.evaluate_all(self.node);
1047                    let nodes: Vec<_> =
1048                        results.iter().filter_map(|r| r.as_node()).collect();
1049                    T::deserialize(SeqDeserializer::new(nodes))
1050                }
1051                FieldKind::OptionalSequence => {
1052                    let results = xpath.evaluate_all(self.node);
1053                    let nodes: Vec<_> =
1054                        results.iter().filter_map(|r| r.as_node()).collect();
1055                    T::deserialize(SeqDeserializer::new(nodes))
1056                }
1057            }
1058        }
1059
1060        fn deserialize_field_inner<'de, T: serde::Deserialize<'de>>(
1061            &self,
1062            field: &FieldDescriptor,
1063        ) -> Result<T, Error> {
1064            let xpath = XPath::parse(field.xpath).map_err(Error::XPath)?;
1065
1066            let result = xpath
1067                .evaluate_single(self.node)
1068                .ok_or_else(|| Error::MissingField(field.name.to_string()))?;
1069
1070            match result {
1071                XPathResult::Node(node) => {
1072                    T::deserialize(XPathDeserializer::new(node))
1073                }
1074                XPathResult::Attribute(value) => {
1075                    T::deserialize(AttributeDeserializer::new(value))
1076                }
1077            }
1078        }
1079
1080        pub fn node(&self) -> Node<'a, 'input> {
1081            self.node
1082        }
1083    }
1084
1085    // Deserializer that always returns None
1086    pub struct OptionNoneDeserializer;
1087
1088    impl<'de> de::Deserializer<'de> for OptionNoneDeserializer {
1089        type Error = Error;
1090
1091        serde::forward_to_deserialize_any! {
1092            bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
1093            byte_buf unit unit_struct newtype_struct seq tuple tuple_struct
1094            map struct enum identifier ignored_any
1095        }
1096
1097        fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
1098        where
1099            V: Visitor<'de>,
1100        {
1101            visitor.visit_none()
1102        }
1103
1104        fn deserialize_option<V>(
1105            self,
1106            visitor: V,
1107        ) -> Result<V::Value, Self::Error>
1108        where
1109            V: Visitor<'de>,
1110        {
1111            visitor.visit_none()
1112        }
1113    }
1114
1115    // Sequence deserializer for Vec fields
1116    pub struct SeqDeserializer<'a, 'input> {
1117        nodes: Vec<Node<'a, 'input>>,
1118    }
1119
1120    impl<'a, 'input> SeqDeserializer<'a, 'input> {
1121        pub fn new(nodes: Vec<Node<'a, 'input>>) -> Self {
1122            SeqDeserializer { nodes }
1123        }
1124    }
1125
1126    impl<'de, 'a, 'input> de::Deserializer<'de> for SeqDeserializer<'a, 'input> {
1127        type Error = Error;
1128
1129        serde::forward_to_deserialize_any! {
1130            bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
1131            byte_buf option unit unit_struct newtype_struct tuple tuple_struct
1132            map struct enum identifier ignored_any
1133        }
1134
1135        fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
1136        where
1137            V: Visitor<'de>,
1138        {
1139            self.deserialize_seq(visitor)
1140        }
1141
1142        fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
1143        where
1144            V: Visitor<'de>,
1145        {
1146            visitor.visit_seq(SeqAccess { nodes: self.nodes, index: 0 })
1147        }
1148    }
1149
1150    struct SeqAccess<'a, 'input> {
1151        nodes: Vec<Node<'a, 'input>>,
1152        index: usize,
1153    }
1154
1155    impl<'de, 'a, 'input> de::SeqAccess<'de> for SeqAccess<'a, 'input> {
1156        type Error = Error;
1157
1158        fn next_element_seed<T>(
1159            &mut self,
1160            seed: T,
1161        ) -> Result<Option<T::Value>, Self::Error>
1162        where
1163            T: de::DeserializeSeed<'de>,
1164        {
1165            if self.index >= self.nodes.len() {
1166                return Ok(None);
1167            }
1168
1169            let node = self.nodes[self.index];
1170            self.index += 1;
1171
1172            let value = seed.deserialize(XPathDeserializer::new(node))?;
1173            Ok(Some(value))
1174        }
1175    }
1176
1177    // Helper function for deserializing from a node with a custom struct
1178    // descriptor
1179    pub fn deserialize_struct_from_node<'de, 'a, 'input, T, F>(
1180        node: Node<'a, 'input>,
1181        descriptor: &'static StructDescriptor,
1182        field_deserializer: F,
1183    ) -> Result<T, Error>
1184    where
1185        F: FnOnce(StructFieldDeserializer<'a, 'input>) -> Result<T, Error>,
1186    {
1187        let deser = StructFieldDeserializer { node, descriptor };
1188        field_deserializer(deser)
1189    }
1190}