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}