component_id_index/
fidl_convert.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::{
6    Index, InstanceId, InstanceIdError, PersistedIndex, PersistedIndexEntry, ValidationError,
7};
8use fidl_fuchsia_component_internal as fcomponent_internal;
9use moniker::{Moniker, MonikerError};
10use thiserror::Error;
11
12#[derive(Error, Clone, Debug, PartialEq)]
13pub enum FidlConversionError {
14    #[error("Missing instances")]
15    MissingInstances,
16    #[error("Missing instance_id")]
17    MissingInstanceId,
18    #[error("Missing moniker")]
19    MissingMoniker,
20    #[error("Invalid instance ID")]
21    InstanceIdError(#[from] InstanceIdError),
22    #[error("Invalid moniker")]
23    MonikerError(#[from] MonikerError),
24    #[error("invalid index")]
25    ValidationError(#[from] ValidationError),
26}
27
28impl TryFrom<fcomponent_internal::ComponentIdIndex> for PersistedIndex {
29    type Error = FidlConversionError;
30
31    fn try_from(index: fcomponent_internal::ComponentIdIndex) -> Result<Self, Self::Error> {
32        let mut instances: Vec<PersistedIndexEntry> = vec![];
33        for entry in index.instances.ok_or_else(|| FidlConversionError::MissingInstances)? {
34            instances.push(PersistedIndexEntry {
35                instance_id: entry
36                    .instance_id
37                    .ok_or_else(|| FidlConversionError::MissingInstanceId)?
38                    .parse::<InstanceId>()?,
39                moniker: Moniker::parse_str(
40                    &entry.moniker.ok_or_else(|| FidlConversionError::MissingMoniker)?,
41                )?,
42            });
43        }
44        Ok(PersistedIndex { instances })
45    }
46}
47
48impl TryFrom<fcomponent_internal::ComponentIdIndex> for Index {
49    type Error = FidlConversionError;
50
51    fn try_from(index: fcomponent_internal::ComponentIdIndex) -> Result<Self, Self::Error> {
52        let persisted_index: PersistedIndex = index.try_into()?;
53        persisted_index.try_into().map_err(FidlConversionError::ValidationError)
54    }
55}
56
57impl From<PersistedIndex> for fcomponent_internal::ComponentIdIndex {
58    fn from(index: PersistedIndex) -> Self {
59        fcomponent_internal::ComponentIdIndex {
60            instances: Some(
61                index
62                    .instances
63                    .into_iter()
64                    .map(|entry| fcomponent_internal::InstanceIdEntry {
65                        instance_id: Some(entry.instance_id.to_string()),
66                        moniker: Some(entry.moniker.to_string()),
67                        ..Default::default()
68                    })
69                    .collect(),
70            ),
71            ..Default::default()
72        }
73    }
74}
75
76impl From<Index> for fcomponent_internal::ComponentIdIndex {
77    fn from(index: Index) -> Self {
78        let persisted_index: PersistedIndex = index.into();
79        persisted_index.into()
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    #[test]
88    fn fidl_native_translation() {
89        let fidl_index = fcomponent_internal::ComponentIdIndex {
90            instances: Some(vec![fcomponent_internal::InstanceIdEntry {
91                instance_id: Some(
92                    "8c90d44863ff67586cf6961081feba4f760decab8bbbee376a3bfbc77b351280".to_string(),
93                ),
94                moniker: Some("a/b/c".to_string()),
95                ..Default::default()
96            }]),
97            ..Default::default()
98        };
99
100        let native_index = PersistedIndex {
101            instances: vec![PersistedIndexEntry {
102                instance_id: "8c90d44863ff67586cf6961081feba4f760decab8bbbee376a3bfbc77b351280"
103                    .parse::<InstanceId>()
104                    .unwrap(),
105                moniker: Moniker::parse_str("a/b/c").unwrap(),
106            }],
107        };
108
109        assert_eq!(native_index, PersistedIndex::try_from(fidl_index.clone()).unwrap());
110        assert_eq!(fidl_index, fcomponent_internal::ComponentIdIndex::from(native_index));
111    }
112
113    #[test]
114    fn missing_instances() {
115        assert_eq!(
116            Some(FidlConversionError::MissingInstances),
117            PersistedIndex::try_from(fcomponent_internal::ComponentIdIndex {
118                ..Default::default()
119            })
120            .err()
121        );
122    }
123
124    #[test]
125    fn missing_instance_id() {
126        assert_eq!(
127            Some(FidlConversionError::MissingInstanceId),
128            PersistedIndex::try_from(fcomponent_internal::ComponentIdIndex {
129                instances: Some(vec![fcomponent_internal::InstanceIdEntry {
130                    instance_id: None,
131                    moniker: Some("a/b/c".to_string()),
132                    ..Default::default()
133                }]),
134                ..Default::default()
135            })
136            .err()
137        );
138    }
139
140    #[test]
141    fn missing_moniker() {
142        assert_eq!(
143            Some(FidlConversionError::MissingMoniker),
144            PersistedIndex::try_from(fcomponent_internal::ComponentIdIndex {
145                instances: Some(vec![fcomponent_internal::InstanceIdEntry {
146                    instance_id: Some(
147                        "8c90d44863ff67586cf6961081feba4f760decab8bbbee376a3bfbc77b351280"
148                            .to_string()
149                    ),
150                    moniker: None,
151                    ..Default::default()
152                }]),
153                ..Default::default()
154            })
155            .err()
156        );
157    }
158}