astarte_interfaces/interface/datastream/
individual.rs1use std::{borrow::Cow, fmt::Display, str::FromStr};
25
26use serde::{Deserialize, Serialize};
27
28use crate::{
29 error::Error,
30 interface::{
31 name::InterfaceName, version::InterfaceVersion, AggregationIndividual, MappingVec, Schema,
32 },
33 mapping::{
34 datastream::individual::DatastreamIndividualMapping, path::MappingPath, MappingError,
35 },
36 schema::{Aggregation, InterfaceJson, InterfaceType, Mapping, Ownership},
37};
38
39#[derive(Debug, PartialEq, Eq, Clone, Deserialize)]
43#[serde(try_from = "InterfaceJson<std::borrow::Cow<str>>")]
44pub struct DatastreamIndividual {
45 pub(crate) name: InterfaceName,
46 pub(crate) version: InterfaceVersion,
47 pub(crate) ownership: Ownership,
48 pub(crate) mappings: MappingVec<DatastreamIndividualMapping>,
49 #[cfg(feature = "doc-fields")]
50 #[cfg_attr(docsrs, doc(cfg(feature = "doc-fields")))]
51 pub(crate) description: Option<String>,
52 #[cfg(feature = "doc-fields")]
53 #[cfg_attr(docsrs, doc(cfg(feature = "doc-fields")))]
54 pub(crate) doc: Option<String>,
55}
56
57impl Schema for DatastreamIndividual {
58 type Mapping = DatastreamIndividualMapping;
59
60 fn name(&self) -> &str {
61 self.name.as_ref()
62 }
63
64 fn interface_name(&self) -> &InterfaceName {
65 &self.name
66 }
67
68 fn version_major(&self) -> i32 {
69 self.version.version_major()
70 }
71
72 fn version_minor(&self) -> i32 {
73 self.version.version_minor()
74 }
75
76 fn version(&self) -> InterfaceVersion {
77 self.version
78 }
79
80 fn interface_type(&self) -> InterfaceType {
81 InterfaceType::Datastream
82 }
83
84 fn ownership(&self) -> Ownership {
85 self.ownership
86 }
87
88 fn aggregation(&self) -> Aggregation {
89 Aggregation::Individual
90 }
91
92 #[cfg(feature = "doc-fields")]
93 #[cfg_attr(docsrs, doc(cfg(feature = "doc-fields")))]
94 fn description(&self) -> Option<&str> {
95 self.description.as_deref()
96 }
97
98 #[cfg(feature = "doc-fields")]
99 #[cfg_attr(docsrs, doc(cfg(feature = "doc-fields")))]
100 fn doc(&self) -> Option<&str> {
101 self.doc.as_deref()
102 }
103
104 fn iter_mappings(&self) -> impl Iterator<Item = &Self::Mapping> {
105 self.mappings.iter()
106 }
107
108 fn mappings_len(&self) -> usize {
109 self.mappings.len()
110 }
111
112 fn iter_interface_mappings(&self) -> impl Iterator<Item = Mapping<Cow<'_, str>>> {
113 self.iter_mappings().map(Mapping::from)
114 }
115}
116
117impl AggregationIndividual for DatastreamIndividual {
118 fn mapping(&self, path: &MappingPath) -> Option<&Self::Mapping> {
119 self.mappings.get(path)
120 }
121}
122
123impl Display for DatastreamIndividual {
124 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125 write!(f, "{}:{}", self.name, self.version)
126 }
127}
128
129impl<T> TryFrom<InterfaceJson<T>> for DatastreamIndividual
130where
131 T: AsRef<str> + Into<String>,
132{
133 type Error = Error;
134
135 fn try_from(value: InterfaceJson<T>) -> Result<Self, Self::Error> {
136 if value.interface_type != InterfaceType::Datastream
137 || value.aggregation.unwrap_or_default() != Aggregation::Individual
138 {
139 return Err(Error::InterfaceConversion {
140 exp_type: InterfaceType::Datastream,
141 exp_aggregation: Aggregation::Individual,
142 got_type: value.interface_type,
143 got_aggregation: value.aggregation.unwrap_or_default(),
144 });
145 }
146
147 let name = InterfaceName::from_str_ref(value.interface_name)?;
148 let version = InterfaceVersion::try_new(value.version_major, value.version_minor)?;
149
150 let mappings = value
151 .mappings
152 .into_iter()
153 .map(DatastreamIndividualMapping::try_from)
154 .collect::<Result<Vec<DatastreamIndividualMapping>, MappingError>>()
155 .and_then(MappingVec::try_from)?;
156
157 Ok(Self {
158 name: name.into_string(),
159 version,
160 ownership: value.ownership,
161 mappings,
162 #[cfg(feature = "doc-fields")]
163 description: value.description.map(T::into),
164 #[cfg(feature = "doc-fields")]
165 doc: value.doc.map(T::into),
166 })
167 }
168}
169
170impl Serialize for DatastreamIndividual {
171 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
172 where
173 S: serde::Serializer,
174 {
175 InterfaceJson::<Cow<str>>::from(self).serialize(serializer)
176 }
177}
178
179impl FromStr for DatastreamIndividual {
180 type Err = Error;
181
182 fn from_str(s: &str) -> Result<Self, Self::Err> {
183 let interface: InterfaceJson<Cow<str>> = serde_json::from_str(s)?;
184
185 Self::try_from(interface)
186 }
187}