diff --git a/fastpair/rust/demo/rust/src/advertisement.rs b/fastpair/rust/demo/rust/src/advertisement.rs index bb3dd601..58cc3338 100644 --- a/fastpair/rust/demo/rust/src/advertisement.rs +++ b/fastpair/rust/demo/rust/src/advertisement.rs @@ -16,7 +16,7 @@ use bluetooth::{BleAddress, BleAdvertisement, ServiceData}; use crate::{ decoder::FpDecoder, - fetcher::{FpFetcher, FpFetcherLocal}, + fetcher::{DeviceInfo, FpFetcher, FpFetcherFs}, }; /// Represents a FP device model ID. @@ -78,7 +78,7 @@ impl FpPairingAdvertisement { let model_id = format!("{}", u32::from_be_bytes(model_id.try_into().unwrap())); // Retrieve device info of the device corresponding to this model ID. - let fetcher = FpFetcherLocal::new(String::from("./local")); + let fetcher = FpFetcherFs::new(String::from("./local")); let device_info = fetcher .get_device_info_from_model_id(&model_id) .expect("Failed to create device info from model ID."); diff --git a/fastpair/rust/demo/rust/src/fetcher.rs b/fastpair/rust/demo/rust/src/fetcher/common.rs similarity index 59% rename from fastpair/rust/demo/rust/src/fetcher.rs rename to fastpair/rust/demo/rust/src/fetcher/common.rs index e94d49ad..ea7ed605 100644 --- a/fastpair/rust/demo/rust/src/fetcher.rs +++ b/fastpair/rust/demo/rust/src/fetcher/common.rs @@ -11,27 +11,11 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -use std::fs; use serde::Deserialize; use crate::advertisement::ModelId; -/// Holds Fast Pair device information parsed from JSON. -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub(crate) struct DeviceInfo { - image_url: String, - name: String, -} - -/// Holds top-level Fast Pair information parsed from JSON. See `local` -/// directory for format. -#[derive(Deserialize)] -struct JsonData { - device: DeviceInfo, -} - /// Types that can fetch Fast Pair data from external storage (e.g. filesystem, /// remote server). pub(crate) trait FpFetcher { @@ -41,36 +25,26 @@ pub(crate) trait FpFetcher { ) -> Result; } -/// A unit struct for retrieving Fast Pair information from the local filesystem. -pub(crate) struct FpFetcherLocal { - path: String, +/// Holds Fast Pair device information parsed from JSON. +#[derive(Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct DeviceInfo { + image_url: String, + name: String, } -impl FpFetcherLocal { - pub(crate) fn new(path: String) -> Self { - FpFetcherLocal { path } - } -} - -impl FpFetcher for FpFetcherLocal { - /// Retrieve device information for the provided Model ID. Currently, - /// this information is saved locally. In the future, this should instead - /// be retrieved from a remote server and cached. - /// b/294456411 - fn get_device_info_from_model_id( - &self, - model_id: &ModelId, - ) -> Result { - let file_path = format!("{}/{}.json", self.path, model_id); - let contents = fs::read_to_string(file_path).expect("Couldn't find or open file."); - - let model_info: JsonData = serde_json::from_str(&contents)?; - - Ok(model_info.device) - } +/// Holds top-level Fast Pair information parsed from JSON. See `local` +/// directory for format. +#[derive(Deserialize)] +pub(super) struct JsonData { + device: DeviceInfo, } impl DeviceInfo { + pub(crate) fn new(image_url: String, name: String) -> Self { + DeviceInfo { image_url, name } + } + pub(crate) fn name(&self) -> &String { &self.name } @@ -79,3 +53,10 @@ impl DeviceInfo { &self.image_url } } + +impl JsonData { + // Returns the `DeviceInfo` associated with parsed self, consuming self. + pub(super) fn device(self) -> DeviceInfo { + self.device + } +} diff --git a/fastpair/rust/demo/rust/src/fetcher/fs.rs b/fastpair/rust/demo/rust/src/fetcher/fs.rs new file mode 100644 index 00000000..ee45955e --- /dev/null +++ b/fastpair/rust/demo/rust/src/fetcher/fs.rs @@ -0,0 +1,49 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::fs; + +use crate::{ + advertisement::ModelId, + fetcher::{DeviceInfo, FpFetcher, JsonData}, +}; + +/// A struct for retrieving Fast Pair information from the local filesystem. +pub(crate) struct FpFetcherFs { + path: String, +} + +impl FpFetcherFs { + pub(crate) fn new(path: String) -> Self { + FpFetcherFs { path } + } +} + +impl FpFetcher for FpFetcherFs { + /// Retrieve device information for the provided Model ID. Currently, + /// this information is saved locally. In the future, this should instead + /// be retrieved from a remote server and cached. + /// b/294456411 + fn get_device_info_from_model_id( + &self, + model_id: &ModelId, + ) -> Result { + let file_path = format!("{}/{}.json", self.path, model_id); + let contents = fs::read_to_string(file_path).expect("Couldn't find or open file."); + + let model_info: JsonData = serde_json::from_str(&contents)?; + + Ok(model_info.device()) + } +} diff --git a/fastpair/rust/demo/rust/src/fetcher/mock.rs b/fastpair/rust/demo/rust/src/fetcher/mock.rs new file mode 100644 index 00000000..93f9351f --- /dev/null +++ b/fastpair/rust/demo/rust/src/fetcher/mock.rs @@ -0,0 +1,43 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ + advertisement::ModelId, + fetcher::{DeviceInfo, FpFetcher}, +}; + +/// A struct for mocking retrieval of Fast Pair data. +pub(crate) struct FpFetcherMock { + get_device_info_from_model_id: Result, +} + +impl FpFetcherMock { + pub(crate) fn new(get_device_info_from_model_id: Result) -> Self { + FpFetcherMock { + get_device_info_from_model_id, + } + } +} + +impl FpFetcher for FpFetcherMock { + fn get_device_info_from_model_id( + &self, + _model_id: &ModelId, + ) -> Result { + match &self.get_device_info_from_model_id { + Ok(result) => Ok(result.clone()), + Err(_) => Err(anyhow::anyhow!("intentional mock error")), + } + } +} diff --git a/fastpair/rust/demo/rust/src/fetcher/mod.rs b/fastpair/rust/demo/rust/src/fetcher/mod.rs new file mode 100644 index 00000000..98772f6e --- /dev/null +++ b/fastpair/rust/demo/rust/src/fetcher/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +pub(crate) mod common; +pub(crate) mod fs; + +#[cfg(test)] +pub(crate) mod mock; + +pub(crate) use common::*; +pub(crate) use fs::*;