[fp-rs] Setting up boilerplate for multiplatform FP Rust.

This commit is contained in:
Lucas Silva Shepard
2023-07-13 16:06:31 -07:00
parent 5306df9251
commit 4e8c66e88b
11 changed files with 298 additions and 5 deletions
+12
View File
@@ -20,3 +20,15 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0"
futures = { version = "0.3", features = ["executor"] }
tracing = "0.1.37"
cfg-if = "1.0.0"
async-trait = "0.1"
[target.'cfg(windows)'.dependencies]
windows = { version = "0.48", features = [
"Devices_Bluetooth",
"Devices_Bluetooth_Advertisement",
"Foundation",
] }
+31
View File
@@ -0,0 +1,31 @@
// 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 async_trait::async_trait;
/// Concrete types implementing this trait are Bluetooth Central devices.
/// They provide methods for retrieving nearby connections and device info.
#[async_trait]
pub trait Adapter: Sized {
/// Retrieve the system-default Bluetooth adapter.
async fn default() -> Result<Self, anyhow::Error>;
}
/// Concrete types implementing this trait represent Bluetooth Peripheral devices.
/// They provide methods for retrieving device info and running device actions,
/// such as pairing.
pub trait Device {
/// Retrieve the name advertised by this device.
fn name(&self) -> Result<String, anyhow::Error>;
}
+29
View File
@@ -0,0 +1,29 @@
// 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.
// Split into separate crate once demo is finished, providing custom error types
// instead of using anyhow.
// b/290070686
pub mod common;
cfg_if::cfg_if! {
if #[cfg(windows)] {
mod windows_ble;
pub use windows_ble::*;
} else {
mod unsupported;
pub use unsupported::*;
}
}
@@ -0,0 +1,38 @@
// 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::pin::Pin;
use async_trait::async_trait;
use futures::stream::Stream;
use super::BleDevice;
use crate::bluetooth::common::Adapter;
/// Concrete type implementing `Adapter`, used for unsupported devices.
/// Every method should panic.
pub struct BleAdapter;
#[async_trait]
impl Adapter for BleAdapter {
async fn default() -> Result<Self, anyhow::Error> {
panic!("Unsupported target platform.");
}
}
mod tests {
use super::*;
// TODO b/288592509 unit tests
}
@@ -0,0 +1,31 @@
// 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::bluetooth::common::Device;
/// Concrete type implementing `Device`, used for unsupported devices.
/// Every method should panic.
pub struct BleDevice;
impl Device for BleDevice {
fn name(&self) -> Result<String, anyhow::Error> {
panic!("Unsupported target platform.")
}
}
mod tests {
use super::*;
// TODO b/288592509 unit tests
}
@@ -0,0 +1,20 @@
// 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.
/// Bluetooth LE module for unsupported devices. Every method panics.
mod adapter;
mod device;
pub use adapter::*;
pub use device::*;
@@ -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 async_trait::async_trait;
use windows::Devices::Bluetooth::BluetoothAdapter;
use crate::bluetooth::common::Adapter;
/// Concrete type implementing `Adapter`, used for Windows BLE.
pub struct BleAdapter {
inner: BluetoothAdapter,
}
#[async_trait]
impl Adapter for BleAdapter {
async fn default() -> Result<Self, anyhow::Error> {
let inner = BluetoothAdapter::GetDefaultAsync()?.await?;
if !inner.IsLowEnergySupported()? {
return Err(anyhow::anyhow!(
"This device's Bluetooth Adapter doesn't support Bluetooth LE Transport type."
));
}
if !inner.IsCentralRoleSupported()? {
return Err(anyhow::anyhow!(
"This device's Bluetooth Adapter doesn't support Bluetooth LE central role."
));
}
Ok(BleAdapter { inner })
}
}
mod tests {
use super::*;
// TODO b/288592509 unit tests
}
@@ -0,0 +1,33 @@
// 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 windows::Devices::Bluetooth::BluetoothLEDevice;
use crate::bluetooth::common::Device;
/// Concrete type implementing `Device`, used for Windows BLE.
pub struct BleDevice {
inner: BluetoothLEDevice,
}
impl Device for BleDevice {
fn name(&self) -> Result<String, anyhow::Error> {
Ok(self.inner.Name()?.to_string_lossy())
}
}
mod tests {
// TODO b/288592509 unit tests
}
@@ -0,0 +1,20 @@
// 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.
/// Bluetooth LE module for Windows devices.
mod adapter;
mod device;
pub use adapter::*;
pub use device::*;
+14 -5
View File
@@ -1,4 +1,4 @@
// Copyright 2020 Google LLC
// 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.
@@ -12,9 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
mod message_stream;
mod types;
use futures::executor;
fn main() {
println!("Fastpair Rust!");
mod bluetooth;
use bluetooth::common::Adapter;
fn main() -> Result<(), anyhow::Error> {
let run = async {
let _adapter = bluetooth::BleAdapter::default().await?;
Ok(())
};
executor::block_on(run)
}
+21
View File
@@ -0,0 +1,21 @@
// 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.
mod tests {
// TODO b/288592509 write integration tests
}