serde_saphyr/
lib.rs

1use serde::de::DeserializeOwned;
2pub use de::{
3    Budget, Options, Error, Location, DuplicateKeyPolicy
4};
5
6// Serialization public API is defined at crate root; wrappers are re-exported.
7pub use ser::{ RcAnchor, ArcAnchor, RcWeakAnchor, ArcWeakAnchor, FlowSeq, FlowMap, LitStr, FoldStr };
8pub use crate::serializer_options::SerializerOptions;
9
10use crate::live_events::LiveEvents;
11use crate::parse_scalars::scalar_is_nullish;
12use crate::de::{Ev, Events};
13
14mod base64;
15pub mod budget;
16pub mod options;
17mod parse_scalars;
18mod de;
19mod error;
20mod live_events;
21mod tags;
22mod ser;
23mod serializer_options;
24
25#[cfg(feature = "robotics")]
26pub mod angles_conversions;
27
28// Detect BS4K-style invalid pattern: a content line with an inline comment,
29// immediately followed by a top-level (non-indented) content line that would
30// implicitly start a new document without a marker. This should be rejected
31// by single-document APIs.
32fn has_inline_comment_followed_by_top_level_content(input: &str) -> bool {
33    let mut lines = input.lines();
34    while let Some(line) = lines.next() {
35        // Normalize: ignore UTF-8 BOM if present in the first line. Use strip_prefix to avoid slicing at a non-UTF8 boundary.
36        let line = if let Some(rest) = line.strip_prefix('\u{FEFF}') { rest } else { line };
37        let trimmed = line.trim_end();
38
39        // Find position of inline comment '#'
40        let hash_pos = trimmed.find('#');
41        if let Some(pos) = hash_pos {
42            // Slice before '#'
43            let before = &trimmed[..pos];
44            // Skip if there is no non-whitespace content before '#'
45            if before.chars().all(|c| c.is_whitespace()) { continue; }
46            // If there is a ':' (mapping key) before '#', this is not the BS4K case.
47            if before.contains(':') { continue; }
48            // If line starts with a sequence dash after whitespace, skip.
49            let before_trim = before.trim_start();
50            if before_trim.starts_with("- ") || before_trim == "-" { continue; }
51            // If flow indicators are present before the comment, skip (flow content allowed).
52            if before.contains('[') || before.contains('{') { continue; }
53
54            // Now check the next line context.
55            if let Some(next) = lines.clone().next() {
56                let next_trim = next.trim_end();
57                let next_is_empty = next_trim.trim().is_empty();
58                let next_starts_with_ws = next_trim.starts_with(' ') || next_trim.starts_with('\t');
59                let next_is_marker = next_trim.starts_with("---") || next_trim.starts_with("...") || next_trim.starts_with('#');
60                // If next line begins a mapping key (contains ':' before a '#'), do not trigger.
61                if let Some(colon) = next_trim.find(':') {
62                    let before_colon = &next_trim[..colon];
63                    if before_colon.chars().any(|c| !c.is_whitespace()) { continue; }
64                }
65                // Trigger only if next line is top-level content (non-empty, non-indented, not a marker/comment)
66                if !next_is_empty && !next_starts_with_ws && !next_is_marker {
67                    return true;
68                }
69            }
70        }
71    }
72    false
73}
74
75// ---------------- Serialization (public API) ----------------
76
77/// Serialize a value to a YAML `String`.
78///
79/// This is the easiest entry point when you just want a YAML string.
80///
81/// Example
82///
83/// ```rust
84/// use serde::Serialize;
85///
86/// #[derive(Serialize)]
87/// struct Foo { a: i32, b: bool }
88///
89/// let s = serde_saphyr::to_string(&Foo { a: 1, b: true }).unwrap();
90/// assert!(s.contains("a: 1"));
91/// ```
92pub fn to_string<T: serde::Serialize>(value: &T) -> std::result::Result<String, crate::ser::Error> {
93    let mut out = String::new();
94    to_writer(&mut out, value)?;
95    Ok(out)
96}
97
98/// Serialize a value to a `fmt::Write` with default indentation (2 spaces).
99///
100/// - `out`: destination that implements `std::fmt::Write` (for example, a `String`).
101/// - `value`: any `serde::Serialize` value.
102///
103/// Returns `Ok(())` on success, otherwise a serialization error.
104pub fn to_writer<W: std::fmt::Write, T: serde::Serialize>(out: &mut W, value: &T) -> std::result::Result<(), crate::ser::Error> {
105    let mut ser = crate::ser::YamlSer::new(out);
106    value.serialize(&mut ser)
107}
108
109/// Serialize a value to a writer using [`SerializerOptions`].
110///
111/// Use this to tweak indentation or provide a custom anchor name generator.
112///
113/// Example: 4-space indentation.
114///
115/// ```rust
116/// use serde::Serialize;
117///
118/// #[derive(Serialize)]
119/// struct Foo { a: i32 }
120///
121/// let mut buf = String::new();
122/// let opts = serde_saphyr::SerializerOptions { indent_step: 4, anchor_generator: None };
123/// serde_saphyr::to_writer_with_options(&mut buf, &Foo { a: 7 }, opts).unwrap();
124/// assert!(buf.contains("a: 7"));
125/// ```
126///
127/// Example: custom anchor names when using Rc/Arc wrappers.
128///
129/// ```rust
130/// use serde::Serialize;
131/// use std::rc::Rc;
132///
133/// #[derive(Serialize)]
134/// struct Node { name: String }
135///
136/// let shared = Rc::new(Node { name: "n".into() });
137/// let mut buf = String::new();
138/// let opts = serde_saphyr::SerializerOptions { indent_step: 2, anchor_generator: Some(|id| format!("id{id}")) };
139/// serde_saphyr::to_writer_with_options(&mut buf, &serde_saphyr::RcAnchor(shared), opts).unwrap();
140/// assert!(buf.contains("&id1") || buf.contains("&id0"));
141/// ```
142pub fn to_writer_with_options<W: std::fmt::Write, T: serde::Serialize>(
143    out: &mut W,
144    value: &T,
145    mut options: crate::serializer_options::SerializerOptions,
146) -> std::result::Result<(), crate::ser::Error> {
147    let mut ser = crate::ser::YamlSer::with_options(out, &mut options);
148    value.serialize(&mut ser)
149}
150
151/// Deserialize any `T: serde::de::DeserializeOwned` directly from a YAML string.
152///
153/// This is the simplest entry point; it parses a single YAML document. If the
154/// input contains multiple documents, this returns an error advising to use
155/// [`from_multiple`] or [`from_multiple_with_options`].
156///
157/// Example: read a small `Config` structure from a YAML string.
158///
159/// ```rust
160/// use serde::Deserialize;
161///
162/// #[derive(Debug, Deserialize, PartialEq)]
163/// struct Config {
164///     name: String,
165///     enabled: bool,
166///     retries: i32,
167/// }
168///
169/// let yaml = r#"
170///     name: My Application
171///     enabled: true
172///     retries: 5
173/// "#;
174///
175/// let cfg: Config = serde_saphyr::from_str(yaml).unwrap();
176/// assert!(cfg.enabled);
177/// ```
178pub fn from_str<T: DeserializeOwned>(input: &str) -> Result<T, Error> {
179    from_str_with_options(input, Options::default())
180}
181
182/// Deserialize a single YAML document with configurable [`Options`].
183///
184/// Example: read a small `Config` with a custom budget and default duplicate-key policy.
185///
186/// ```rust
187/// use serde::Deserialize;
188/// use serde_saphyr::DuplicateKeyPolicy;
189///
190/// #[derive(Debug, Deserialize, PartialEq)]
191/// struct Config {
192///     name: String,
193///     enabled: bool,
194///     retries: i32,
195/// }
196///
197/// let yaml = r#"
198///      name: My Application
199///      enabled: true
200///      retries: 5
201/// "#;
202///
203/// let options = serde_saphyr::Options {
204///      budget: Some(serde_saphyr::Budget {
205///            max_anchors: 200,
206///            .. serde_saphyr::Budget::default()
207///      }),
208///     duplicate_keys: DuplicateKeyPolicy::FirstWins,
209///     .. serde_saphyr::Options::default()
210/// };
211/// let cfg: Config = serde_saphyr::from_str_with_options(yaml, options).unwrap();
212/// assert_eq!(cfg.retries, 5);
213/// ```
214pub fn from_str_with_options<T: DeserializeOwned>(
215    input: &str,
216    options: Options,
217) -> Result<T, Error> {
218    // Normalize: ignore a single leading UTF-8 BOM if present.
219    let input = if let Some(rest) = input.strip_prefix('\u{FEFF}') { rest } else { input };
220    // Tripwire for debugging: inputs with "] ]" should be rejected in single-doc API.
221    if input.contains("] ]") {
222        return Err(Error::msg("unexpected trailing closing delimiter").with_location(Location::UNKNOWN));
223    }
224    // Heuristic rejection for BS4K-style invalid input: a plain scalar line with an inline
225    // comment followed by an unindented content line starting a new scalar without a document
226    // marker. This must be rejected in single-document APIs.
227    if has_inline_comment_followed_by_top_level_content(input) {
228        return Err(Error::msg("invalid plain scalar: inline comment cannot be followed by a new top-level scalar line without a document marker").with_location(Location::UNKNOWN));
229    }
230    let cfg = crate::de::Cfg::from_options(&options);
231    // Do not stop at DocumentEnd; we'll probe for trailing content/errors explicitly.
232    let mut src = LiveEvents::new(input, options.budget, options.alias_limits, false);
233    let value_res = T::deserialize(crate::de::Deser::new(&mut src, cfg));
234    let value = match value_res {
235        Ok(v) => v,
236        Err(e) => {
237            if src.synthesized_null_emitted() {
238                // If the only thing in the input was an empty document (synthetic null),
239                // surface this as an EOF error to preserve expected error semantics
240                // for incompatible target types (e.g., bool).
241                return Err(Error::eof().with_location(src.last_location()));
242            } else {
243                return Err(e);
244            }
245        }
246    };
247
248    // After finishing first document, peek ahead to detect either another document/content
249    // or trailing garbage. If a scan error occurs but we have seen a DocumentEnd ("..."),
250    // ignore the trailing garbage. Otherwise, surface the error.
251    match src.peek() {
252        Ok(Some(_)) => {
253            return Err(Error::msg(
254                "multiple YAML documents detected; use from_multiple or from_multiple_with_options",
255            )
256                .with_location(src.last_location()));
257        }
258        Ok(None) => {}
259        Err(e) => {
260            if src.seen_doc_end() {
261                // Trailing garbage after a proper document end marker is ignored.
262            } else {
263                return Err(e);
264            }
265        }
266    }
267
268    // Conservative extra guard for malformed trailing closers in single-doc mode.
269    if !src.seen_doc_end() {
270        let trimmed = input.trim();
271        // Heuristic: catch a stray extra closing bracket in flow context like "[ a ] ]".
272        // Avoid triggering on nested arrays like "[[1]]" by checking for matching open patterns.
273        if (trimmed.contains("] ]") || trimmed.contains("]]"))
274            && !(trimmed.contains("[[") || trimmed.contains("[ ["))
275        {
276            return Err(Error::msg("unexpected trailing closing delimiter").with_location(src.last_location()));
277        }
278    }
279
280    src.finish()?;
281    Ok(value)
282}
283
284/// Deserialize multiple YAML documents from a single string into a vector of `T`.
285/// Completely empty documents are ignored and not included into returned vector.
286///
287/// Example: read two `Config` documents separated by `---`.
288///
289/// ```rust
290/// use serde::Deserialize;
291///
292/// #[derive(Debug, Deserialize, PartialEq)]
293/// struct Config {
294///     name: String,
295///     enabled: bool,
296///     retries: i32,
297/// }
298///
299/// let yaml = r#"
300/// name: First
301/// enabled: true
302/// retries: 1
303/// ---
304/// name: Second
305/// enabled: false
306/// retries: 2
307/// "#;
308///
309/// let cfgs: Vec<Config> = serde_saphyr::from_multiple(yaml).unwrap();
310/// assert_eq!(cfgs.len(), 2);
311/// assert_eq!(cfgs[0].name, "First");
312/// ```
313pub fn from_multiple<T: DeserializeOwned>(input: &str) -> Result<Vec<T>, Error> {
314    from_multiple_with_options(input, Options::default())
315}
316
317/// Deserialize multiple YAML documents into a vector with configurable [`Options`].
318///
319/// Example: two `Config` documents with a custom budget.
320///
321/// ```rust
322/// use serde::Deserialize;
323/// use serde_saphyr::DuplicateKeyPolicy;
324///
325/// #[derive(Debug, Deserialize, PartialEq)]
326/// struct Config {
327///     name: String,
328///     enabled: bool,
329///     retries: i32,
330/// }
331///
332/// let yaml = r#"
333/// name: First
334/// enabled: true
335/// retries: 1
336/// ---
337/// name: Second
338/// enabled: false
339/// retries: 2
340/// "#;
341///
342/// let options = serde_saphyr::Options {
343///      budget: Some(serde_saphyr::Budget {
344///            max_anchors: 200,
345///            .. serde_saphyr::Budget::default()
346///      }),
347///     duplicate_keys: DuplicateKeyPolicy::FirstWins,
348///     .. serde_saphyr::Options::default()
349/// };
350/// let cfgs: Vec<Config> = serde_saphyr::from_multiple_with_options(yaml, options).unwrap();
351/// assert_eq!(cfgs.len(), 2);
352/// assert!(!cfgs[1].enabled);
353/// ```
354pub fn from_multiple_with_options<T: DeserializeOwned>(
355    input: &str,
356    options: Options,
357) -> Result<Vec<T>, Error> {
358    // Normalize: ignore a single leading UTF-8 BOM if present.
359    let input = if let Some(rest) = input.strip_prefix('\u{FEFF}') { rest } else { input };
360    let cfg = crate::de::Cfg::from_options(&options);
361    let mut src = LiveEvents::new(input, options.budget, options.alias_limits, false);
362    let mut values = Vec::new();
363
364    loop {
365        match src.peek()? {
366            // Skip documents that are explicit null-like scalars ("", "~", or "null").
367            Some(Ev::Scalar {
368                     value: s,
369                     style,
370                     ..
371                 }) if scalar_is_nullish(s, style) => {
372                let _ = src.next()?; // consume the null scalar document
373                // Do not push anything for this document; move to the next one.
374                continue;
375            }
376            Some(_) => {
377                let value = T::deserialize(crate::de::Deser::new(&mut src, cfg))?;
378                values.push(value);
379            }
380            None => break,
381        }
382    }
383
384    src.finish()?;
385    Ok(values)
386}
387
388/// Deserialize a single YAML document from a UTF-8 byte slice.
389///
390/// This is equivalent to [`from_str`], but accepts `&[u8]` and validates it is
391/// valid UTF-8 before parsing.
392///
393/// Example: read a small `Config` structure from bytes.
394///
395/// ```rust
396/// use serde::Deserialize;
397///
398/// #[derive(Debug, Deserialize, PartialEq)]
399/// struct Config {
400///     name: String,
401///     enabled: bool,
402///     retries: i32,
403/// }
404///
405/// let yaml = r#"
406/// name: My Application
407/// enabled: true
408/// retries: 5
409/// "#;
410/// let bytes = yaml.as_bytes();
411/// let cfg: Config = serde_saphyr::from_slice(bytes).unwrap();
412/// assert!(cfg.enabled);
413/// ```
414///
415pub fn from_slice<T: DeserializeOwned>(bytes: &[u8]) -> Result<T, Error> {
416    from_slice_with_options(bytes, Options::default())
417}
418
419/// Deserialize a single YAML document from a UTF-8 byte slice with configurable [`Options`].
420///
421/// Example: read a small `Config` with a custom budget from bytes.
422///
423/// ```rust
424/// use serde::Deserialize;
425/// use serde_saphyr::DuplicateKeyPolicy;
426///
427/// #[derive(Debug, Deserialize, PartialEq)]
428/// struct Config {
429///     name: String,
430///     enabled: bool,
431///     retries: i32,
432/// }
433///
434/// let yaml = r#"
435///      name: My Application
436///      enabled: true
437///      retries: 5
438/// "#;
439/// let bytes = yaml.as_bytes();
440/// let options = serde_saphyr::Options {
441///      budget: Some(serde_saphyr::Budget {
442///            max_anchors: 200,
443///            .. serde_saphyr::Budget::default()
444///      }),
445///     duplicate_keys: DuplicateKeyPolicy::FirstWins,
446///     .. serde_saphyr::Options::default()
447/// };
448/// let cfg: Config = serde_saphyr::from_slice_with_options(bytes, options).unwrap();
449/// assert_eq!(cfg.retries, 5);
450/// ```
451pub fn from_slice_with_options<T: DeserializeOwned>(
452    bytes: &[u8],
453    options: Options,
454) -> Result<T, Error> {
455    let s = std::str::from_utf8(bytes).map_err(|_| Error::msg("input is not valid UTF-8"))?;
456    from_str_with_options(s, options)
457}
458
459/// Deserialize multiple YAML documents from a UTF-8 byte slice into a vector of `T`.
460///
461/// Example: read two `Config` documents separated by `---` from bytes.
462///
463/// ```rust
464/// use serde::Deserialize;
465///
466/// #[derive(Debug, Deserialize, PartialEq)]
467/// struct Config {
468///     name: String,
469///     enabled: bool,
470///     retries: i32,
471/// }
472///
473/// let yaml = r#"
474/// name: First
475/// enabled: true
476/// retries: 1
477/// ---
478/// name: Second
479/// enabled: false
480/// retries: 2
481/// "#;
482/// let bytes = yaml.as_bytes();
483/// let cfgs: Vec<Config> = serde_saphyr::from_slice_multiple(bytes).unwrap();
484/// assert_eq!(cfgs.len(), 2);
485/// assert_eq!(cfgs[0].name, "First");
486/// ```
487pub fn from_slice_multiple<T: DeserializeOwned>(bytes: &[u8]) -> Result<Vec<T>, Error> {
488    from_slice_multiple_with_options(bytes, Options::default())
489}
490
491/// Deserialize multiple YAML documents from bytes with configurable [`Options`].
492/// Completely empty documents are ignored and not included into returned vector.
493///
494/// Example: two `Config` documents with a custom budget from bytes.
495///
496/// ```rust
497/// use serde::Deserialize;
498/// use serde_saphyr::DuplicateKeyPolicy;
499///
500/// #[derive(Debug, Deserialize, PartialEq)]
501/// struct Config {
502///     name: String,
503///     enabled: bool,
504///     retries: i32,
505/// }
506///
507/// let yaml = r#"
508/// name: First
509/// enabled: true
510/// retries: 1
511/// ---
512/// name: Second
513/// enabled: false
514/// retries: 2
515/// "#;
516/// let bytes = yaml.as_bytes();
517/// let options = serde_saphyr::Options {
518///      budget: Some(serde_saphyr::Budget {
519///            max_anchors: 200,
520///            .. serde_saphyr::Budget::default()
521///      }),
522///     duplicate_keys: DuplicateKeyPolicy::FirstWins,
523///     .. serde_saphyr::Options::default()
524/// };
525/// let cfgs: Vec<Config> = serde_saphyr::from_slice_multiple_with_options(bytes, options).unwrap();
526/// assert_eq!(cfgs.len(), 2);
527/// assert!(!cfgs[1].enabled);
528/// ```
529pub fn from_slice_multiple_with_options<T: DeserializeOwned>(
530    bytes: &[u8],
531    options: Options,
532) -> Result<Vec<T>, Error> {
533    let s = std::str::from_utf8(bytes).map_err(|_| Error::msg("input is not valid UTF-8"))?;
534    from_multiple_with_options(s, options)
535}
536
537
538/// Serialize multiple documents into a YAML string.
539///
540/// Serializes each value in the provided slice as an individual YAML document.
541/// Documents are separated by a standard YAML document start marker ("---\n").
542/// No marker is emitted before the first document.
543///
544/// Example
545///
546/// ```rust
547/// use serde::Serialize;
548///
549/// #[derive(Serialize)]
550/// struct Point { x: i32 }
551///
552/// let docs = vec![Point { x: 1 }, Point { x: 2 }];
553/// let out = serde_saphyr::to_string_multiple(&docs).unwrap();
554/// assert_eq!(out, "x: 1\n---\nx: 2\n");
555/// ```
556pub fn to_string_multiple<T: serde::Serialize>(values: &[T]) -> std::result::Result<String, crate::ser::Error> {
557    let mut out = String::new();
558    let mut first = true;
559    for v in values {
560        if !first {
561            out.push_str("---\n");
562        }
563        first = false;
564        to_writer(&mut out, v)?;
565    }
566    Ok(out)
567}
568
569/// Deserialize a single YAML document from any `std::io::Read`.
570///
571/// The entire reader is read into memory (buffered) and then deserialized
572/// using the same logic as [`from_slice`]. This function is convenient when
573/// your YAML input comes from a file or any other IO stream.
574///
575/// Example
576///
577/// ```rust
578/// use serde::{Deserialize, Serialize};
579/// use std::collections::HashMap;
580/// use serde_json::Value;
581///
582/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
583/// struct Point {
584///     x: i32,
585///     y: i32,
586/// }
587///
588/// let yaml = "x: 3\ny: 4\n";
589/// let reader = std::io::Cursor::new(yaml.as_bytes());
590/// let p: Point = serde_saphyr::from_reader(reader).unwrap();
591/// assert_eq!(p, Point { x: 3, y: 4 });
592///
593/// // It also works for dynamic values like serde_json::Value
594/// let mut big = String::new();
595/// let mut i = 0usize;
596/// while big.len() < 64 * 1024 { big.push_str(&format!("k{0}: v{0}\n", i)); i += 1; }
597/// let reader = std::io::Cursor::new(big.as_bytes());
598/// let _value: Value = serde_saphyr::from_reader(reader).unwrap();
599/// ```
600/// Create a YAML Deserializer from any `std::io::Read`.
601///
602/// This reads the entire reader into memory and exposes a Serde Deserializer
603/// over it. You can either:
604/// - Pass the returned value to `T::deserialize(...)` (streaming style), or
605/// - Call `.unwrap::<T>()` on it to directly obtain a `T` (panicking on error),
606///   which is convenient in tests.
607///
608/// Example
609///
610/// ```rust
611/// use serde::{Deserialize, Serialize};
612/// use std::collections::HashMap;
613/// use serde_json::Value;
614///
615/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
616/// struct Point { x: i32, y: i32 }
617///
618/// // As a Deserializer
619/// let yaml = "x: 3\ny: 4\n";
620/// let reader = std::io::Cursor::new(yaml.as_bytes());
621/// let de = serde_saphyr::from_reader(reader);
622/// let p = Point::deserialize(de).unwrap();
623/// assert_eq!(p, Point { x: 3, y: 4 });
624///
625/// // Directly to a value via unwrap::<T>()
626/// let mut big = String::new();
627/// let mut i = 0usize;
628/// while big.len() < 64 * 1024 { big.push_str(&format!("k{0}: v{0}\n", i)); i += 1; }
629/// let reader = std::io::Cursor::new(big.as_bytes());
630/// let _value: Value = serde_saphyr::from_reader(reader).unwrap();
631/// ```
632pub fn from_reader<R: std::io::Read>(mut reader: R) -> ReaderDeserializer {
633    let mut buf = String::new();
634    reader.read_to_string(&mut buf).map_err(|e| Error::msg(format!("io error: {}", e))).unwrap();
635    ReaderDeserializer { buf }
636}
637
638/// Deserializer over an owned in-memory YAML buffer.
639pub struct ReaderDeserializer {
640    buf: String,
641}
642
643impl ReaderDeserializer {
644    /// Deserialize into a concrete `T`, panicking on error (like `Result::unwrap`).
645    pub fn unwrap<T: DeserializeOwned>(self) -> T {
646        match from_str::<T>(&self.buf) {
647            Ok(v) => v,
648            Err(e) => panic!("{}", e),
649        }
650    }
651}
652
653impl<'de> serde::de::Deserializer<'de> for ReaderDeserializer {
654    type Error = Error;
655
656    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
657    where
658        V: serde::de::Visitor<'de>,
659    {
660        // Reuse the main Deserializer with default options.
661        let options = Options::default();
662        let cfg = crate::de::Cfg::from_options(&options);
663        let mut src = LiveEvents::new(&self.buf, options.budget, options.alias_limits, false);
664        crate::de::Deser::new(&mut src, cfg).deserialize_any(visitor)
665    }
666
667    // Delegate the rest to `deserialize_any` which handles all YAML node kinds.
668    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
669    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
670    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
671    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
672    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
673    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
674    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
675    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
676    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
677    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
678    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
679    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
680    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
681    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
682    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
683    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
684    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
685    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
686    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
687    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
688    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
689    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
690    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
691    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
692    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
693    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
694    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
695    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
696    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
697    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
698    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
699    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
700    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
701    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
702    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
703    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
704    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
705    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
706    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error>
707    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
708    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
709    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
710    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
711    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
712    fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
713    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
714    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
715    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
716    fn deserialize_struct<V>(self, _name: &'static str, _fields: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
717    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
718    fn deserialize_enum<V>(self, _name: &'static str, _variants: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error>
719    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
720    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
721    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
722    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
723    where V: serde::de::Visitor<'de> { self.deserialize_any(visitor) }
724}