| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use crate::{ |
| Index, InstanceId, InstanceIdError, PersistedIndex, PersistedIndexEntry, ValidationError, |
| }; |
| use fidl_fuchsia_component_internal as fcomponent_internal; |
| use moniker::{Moniker, MonikerBase, MonikerError}; |
| use thiserror::Error; |
| |
| #[derive(Error, Clone, Debug, PartialEq)] |
| pub enum FidlConversionError { |
| #[error("Missing instances")] |
| MissingInstances, |
| #[error("Missing instance_id")] |
| MissingInstanceId, |
| #[error("Missing moniker")] |
| MissingMoniker, |
| #[error("Invalid instance ID")] |
| InstanceIdError(#[from] InstanceIdError), |
| #[error("Invalid moniker")] |
| MonikerError(#[from] MonikerError), |
| #[error("invalid index")] |
| ValidationError(#[from] ValidationError), |
| } |
| |
| impl TryFrom<fcomponent_internal::ComponentIdIndex> for PersistedIndex { |
| type Error = FidlConversionError; |
| |
| fn try_from(index: fcomponent_internal::ComponentIdIndex) -> Result<Self, Self::Error> { |
| let mut instances: Vec<PersistedIndexEntry> = vec![]; |
| for entry in index.instances.ok_or_else(|| FidlConversionError::MissingInstances)? { |
| instances.push(PersistedIndexEntry { |
| instance_id: entry |
| .instance_id |
| .ok_or_else(|| FidlConversionError::MissingInstanceId)? |
| .parse::<InstanceId>()?, |
| moniker: Moniker::parse_str( |
| &entry.moniker.ok_or_else(|| FidlConversionError::MissingMoniker)?, |
| )?, |
| }); |
| } |
| Ok(PersistedIndex { instances }) |
| } |
| } |
| |
| impl TryFrom<fcomponent_internal::ComponentIdIndex> for Index { |
| type Error = FidlConversionError; |
| |
| fn try_from(index: fcomponent_internal::ComponentIdIndex) -> Result<Self, Self::Error> { |
| let persisted_index: PersistedIndex = index.try_into()?; |
| persisted_index.try_into().map_err(FidlConversionError::ValidationError) |
| } |
| } |
| |
| impl From<PersistedIndex> for fcomponent_internal::ComponentIdIndex { |
| fn from(index: PersistedIndex) -> Self { |
| fcomponent_internal::ComponentIdIndex { |
| instances: Some( |
| index |
| .instances |
| .into_iter() |
| .map(|entry| fcomponent_internal::InstanceIdEntry { |
| instance_id: Some(entry.instance_id.to_string()), |
| moniker: Some(entry.moniker.to_string()), |
| ..Default::default() |
| }) |
| .collect(), |
| ), |
| ..Default::default() |
| } |
| } |
| } |
| |
| impl From<Index> for fcomponent_internal::ComponentIdIndex { |
| fn from(index: Index) -> Self { |
| let persisted_index: PersistedIndex = index.into(); |
| persisted_index.into() |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| |
| #[test] |
| fn fidl_native_translation() { |
| let fidl_index = fcomponent_internal::ComponentIdIndex { |
| instances: Some(vec![fcomponent_internal::InstanceIdEntry { |
| instance_id: Some( |
| "8c90d44863ff67586cf6961081feba4f760decab8bbbee376a3bfbc77b351280".to_string(), |
| ), |
| moniker: Some("a/b/c".to_string()), |
| ..Default::default() |
| }]), |
| ..Default::default() |
| }; |
| |
| let native_index = PersistedIndex { |
| instances: vec![PersistedIndexEntry { |
| instance_id: "8c90d44863ff67586cf6961081feba4f760decab8bbbee376a3bfbc77b351280" |
| .parse::<InstanceId>() |
| .unwrap(), |
| moniker: Moniker::parse_str("a/b/c").unwrap(), |
| }], |
| }; |
| |
| assert_eq!(native_index, PersistedIndex::try_from(fidl_index.clone()).unwrap()); |
| assert_eq!(fidl_index, fcomponent_internal::ComponentIdIndex::from(native_index)); |
| } |
| |
| #[test] |
| fn missing_instances() { |
| assert_eq!( |
| Some(FidlConversionError::MissingInstances), |
| PersistedIndex::try_from(fcomponent_internal::ComponentIdIndex { |
| ..Default::default() |
| }) |
| .err() |
| ); |
| } |
| |
| #[test] |
| fn missing_instance_id() { |
| assert_eq!( |
| Some(FidlConversionError::MissingInstanceId), |
| PersistedIndex::try_from(fcomponent_internal::ComponentIdIndex { |
| instances: Some(vec![fcomponent_internal::InstanceIdEntry { |
| instance_id: None, |
| moniker: Some("a/b/c".to_string()), |
| ..Default::default() |
| }]), |
| ..Default::default() |
| }) |
| .err() |
| ); |
| } |
| |
| #[test] |
| fn missing_moniker() { |
| assert_eq!( |
| Some(FidlConversionError::MissingMoniker), |
| PersistedIndex::try_from(fcomponent_internal::ComponentIdIndex { |
| instances: Some(vec![fcomponent_internal::InstanceIdEntry { |
| instance_id: Some( |
| "8c90d44863ff67586cf6961081feba4f760decab8bbbee376a3bfbc77b351280" |
| .to_string() |
| ), |
| moniker: None, |
| ..Default::default() |
| }]), |
| ..Default::default() |
| }) |
| .err() |
| ); |
| } |
| } |