Skip to main content

nominal_api/conjure/objects/ingest/api/
avro_stream_opts.rs

1/// Options for ingesting Avro data with the following schema. This is a "stream-like" file format to support
2/// use cases where a columnar/tabular format does not make sense. This closely matches Nominal's streaming
3/// API, making it useful for use cases where network connection drops during streaming and a backup file needs
4/// to be created.
5///
6/// If this schema is not used, will result in a failed ingestion.
7/// {
8///     "type": "record",
9///     "name": "AvroStream",
10///     "namespace": "io.nominal.ingest",
11///     "fields": [
12///         {
13///             "name": "channel",
14///             "type": "string",
15///             "doc": "Channel/series name (e.g., 'vehicle_id', 'col_1', 'temperature')",
16///         },
17///         {
18///             "name": "timestamps",
19///             "type": {"type": "array", "items": "long"},
20///             "doc": "Array of numeric timestamps; see timestampType for interpretation",
21///         },
22///         {
23///             "name": "values",
24///             "type": {"type": "array", "items": ["double", "string"]},
25///             "doc": "Array of values. Can either be doubles or strings",
26///         },
27///         {
28///             "name": "tags",
29///             "type": {"type": "map", "values": "string"},
30///             "default": {},
31///             "doc": "Key-value metadata tags",
32///         },
33///     ],
34/// }
35#[derive(
36    Debug,
37    Clone,
38    conjure_object::serde::Serialize,
39    conjure_object::serde::Deserialize,
40    PartialEq,
41    Eq,
42    PartialOrd,
43    Ord,
44    Hash
45)]
46#[serde(crate = "conjure_object::serde")]
47#[conjure_object::private::staged_builder::staged_builder]
48#[builder(crate = conjure_object::private::staged_builder, update, inline)]
49pub struct AvroStreamOpts {
50    #[builder(custom(type = super::IngestSource, convert = Box::new))]
51    #[serde(rename = "source")]
52    source: Box<super::IngestSource>,
53    #[builder(custom(type = super::DatasetIngestTarget, convert = Box::new))]
54    #[serde(rename = "target")]
55    target: Box<super::DatasetIngestTarget>,
56    #[builder(default, into)]
57    #[serde(
58        rename = "additionalFileTags",
59        skip_serializing_if = "Option::is_none",
60        default
61    )]
62    additional_file_tags: Option<std::collections::BTreeMap<String, String>>,
63    #[builder(
64        default,
65        custom(
66            type = impl
67            Into<Option<super::AvroNumericTimestampType>>,
68            convert = |v|v.into().map(Box::new)
69        )
70    )]
71    #[serde(rename = "timestampType", skip_serializing_if = "Option::is_none", default)]
72    timestamp_type: Option<Box<super::AvroNumericTimestampType>>,
73}
74impl AvroStreamOpts {
75    /// Constructs a new instance of the type.
76    #[inline]
77    pub fn new(source: super::IngestSource, target: super::DatasetIngestTarget) -> Self {
78        Self::builder().source(source).target(target).build()
79    }
80    #[inline]
81    pub fn source(&self) -> &super::IngestSource {
82        &*self.source
83    }
84    #[inline]
85    pub fn target(&self) -> &super::DatasetIngestTarget {
86        &*self.target
87    }
88    /// Specifies a tag set to apply to all data in the file.
89    #[inline]
90    pub fn additional_file_tags(
91        &self,
92    ) -> Option<&std::collections::BTreeMap<String, String>> {
93        self.additional_file_tags.as_ref().map(|o| &*o)
94    }
95    /// How to interpret the numeric values in the `timestamps` array. Defaults to epoch-nanoseconds
96    /// when omitted, matching the original contract of this API.
97    #[inline]
98    pub fn timestamp_type(&self) -> Option<&super::AvroNumericTimestampType> {
99        self.timestamp_type.as_ref().map(|o| &**o)
100    }
101}