Skip to main content

ion_rs/lazy/encoder/
annotate.rs

1use crate::lazy::encoder::annotation_seq::AnnotationSeq;
2use crate::lazy::encoder::value_writer::{AnnotatableWriter, ValueWriter};
3use crate::lazy::encoder::write_as_ion::WriteAsIon;
4use crate::IonResult;
5
6/// Associates a value to serialize with a sequence of annotations.
7pub struct Annotated<'a, T: ?Sized, A: 'a> {
8    value: &'a T,
9    annotations: A,
10}
11
12/// Provides implementors with an extension method ([`annotated_with`](Annotatable::annotated_with))
13/// that allows them to be serialized with an associated sequence of annotations.
14pub trait Annotatable {
15    /// Pairs a reference to the provided value with a slice containing annotations.
16    ///
17    /// ```
18    ///# use ion_rs::IonResult;
19    ///# #[cfg(feature = "experimental-reader-writer")]
20    ///# fn main() -> IonResult<()> {
21    /// use ion_rs::{Annotatable, Element, IonData, Writer, v1_0::Text};
22    ///
23    /// let mut buffer = vec![];
24    /// let mut writer = Writer::new(Text, &mut buffer)?;
25    ///
26    /// writer.write(42_usize.annotated_with(["foo", "bar", "baz"]))?.flush()?;
27    ///
28    /// let expected = Element::read_one("foo::bar::baz::42")?;
29    /// let actual = Element::read_one(&buffer)?;
30    ///
31    /// assert!(IonData::eq(&expected, &actual));
32    ///# Ok(())
33    ///# }
34    ///# #[cfg(not(feature = "experimental-reader-writer"))]
35    ///# fn main() -> IonResult<()> { Ok(()) }
36    /// ```
37    #[cfg_attr(not(feature = "experimental-reader-writer"), allow(dead_code))]
38    fn annotated_with<'a, A: 'a>(&'a self, annotations: A) -> Annotated<'a, Self, A>
39    where
40        &'a A: AnnotationSeq<'a>;
41}
42
43// Any Rust value that can be serialized as an Ion value can call `annotate`.
44impl<T> Annotatable for T
45where
46    T: ?Sized + WriteAsIon,
47{
48    fn annotated_with<'a, A: 'a>(&'a self, annotations: A) -> Annotated<'a, Self, A>
49    where
50        &'a A: AnnotationSeq<'a>,
51    {
52        Annotated {
53            value: self,
54            annotations,
55        }
56    }
57}
58
59// The `Annotated` struct implements `WriteAsIon` by serializing its sequence of annotations
60// and then invoking the inner value's implementation of `WriteAsIon`.
61impl<'annotations, T, A: 'annotations> WriteAsIon for Annotated<'annotations, T, A>
62where
63    for<'x> &'x A: AnnotationSeq<'x>,
64    T: WriteAsIon,
65{
66    fn write_as_ion<V: ValueWriter>(&self, writer: V) -> IonResult<()> {
67        let value_writer = <V as AnnotatableWriter>::with_annotations(writer, &self.annotations)?;
68        self.value.write_as_ion(value_writer)
69    }
70}