Skip to content
Snippets Groups Projects
Commit e2a11d18 authored by Sonny Sasaka's avatar Sonny Sasaka Committed by Gerrit Code Review
Browse files

Merge "floss: Add dbus_projection unit test"

parents 41c94bb7 84f14c9c
No related branches found
No related tags found
No related merge requests found
......@@ -4,4 +4,6 @@ version = "0.1.0"
edition = "2018"
[dependencies]
dbus_macros = { path = "dbus_macros" }
dbus = "0.9.2"
dbus-tokio = "0.7.3"
......@@ -7,6 +7,6 @@ edition = "2018"
proc-macro = true
[dependencies]
syn = "1.0"
syn = { version = "1.0.58", features = ['default', 'full'] }
quote = "1.0"
proc-macro2 = "1.0"
......@@ -183,13 +183,13 @@ pub fn generate_dbus_exporter(attr: TokenStream, item: TokenStream) -> TokenStre
pub fn #fn_ident<T: 'static + #api_iface_ident + Send + ?Sized, P: Into<dbus::Path<'static>>>(
path: P,
conn: std::sync::Arc<SyncConnection>,
conn: std::sync::Arc<dbus::nonblock::SyncConnection>,
cr: &mut dbus_crossroads::Crossroads,
obj: #obj_type,
disconnect_watcher: std::sync::Arc<std::sync::Mutex<dbus_projection::DisconnectWatcher>>,
) {
fn get_iface_token<T: #api_iface_ident + Send + ?Sized>(
conn: std::sync::Arc<SyncConnection>,
conn: std::sync::Arc<dbus::nonblock::SyncConnection>,
cr: &mut dbus_crossroads::Crossroads,
disconnect_watcher: std::sync::Arc<std::sync::Mutex<dbus_projection::DisconnectWatcher>>,
) -> dbus_crossroads::IfaceToken<#obj_type> {
......@@ -314,7 +314,7 @@ pub fn dbus_propmap(attr: TokenStream, item: TokenStream) -> TokenStream {
fn from_dbus(
data__: dbus::arg::PropMap,
conn__: Option<std::sync::Arc<SyncConnection>>,
conn__: Option<std::sync::Arc<dbus::nonblock::SyncConnection>>,
remote__: Option<dbus::strings::BusName<'static>>,
disconnect_watcher__: Option<std::sync::Arc<std::sync::Mutex<dbus_projection::DisconnectWatcher>>>,
) -> Result<#struct_ident, Box<dyn std::error::Error>> {
......@@ -440,7 +440,7 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream {
}
struct #struct_ident {
conn: std::sync::Arc<SyncConnection>,
conn: std::sync::Arc<dbus::nonblock::SyncConnection>,
remote: dbus::strings::BusName<'static>,
objpath: Path<'static>,
disconnect_watcher: std::sync::Arc<std::sync::Mutex<DisconnectWatcher>>,
......@@ -465,7 +465,7 @@ pub fn dbus_proxy_obj(attr: TokenStream, item: TokenStream) -> TokenStream {
fn from_dbus(
objpath__: Path<'static>,
conn__: Option<std::sync::Arc<SyncConnection>>,
conn__: Option<std::sync::Arc<dbus::nonblock::SyncConnection>>,
remote__: Option<dbus::strings::BusName<'static>>,
disconnect_watcher__: Option<std::sync::Arc<std::sync::Mutex<DisconnectWatcher>>>,
) -> Result<Box<dyn #trait_ + Send>, Box<dyn std::error::Error>> {
......@@ -559,10 +559,18 @@ pub fn generate_dbus_arg(_item: TokenStream) -> TokenStream {
type RustType = dbus::arg::PropMap;
fn ref_arg_to_rust(
arg: &(dyn dbus::arg::RefArg + 'static),
_name: String,
name: String,
) -> Result<Self::RustType, Box<dyn Error>> {
let mut map: dbus::arg::PropMap = std::collections::HashMap::new();
let mut iter = arg.as_iter().unwrap();
let mut iter = match arg.as_iter() {
None => {
return Err(Box::new(DBusArgError::new(String::from(format!(
"{} is not iterable",
name,
)))))
}
Some(item) => item,
};
let mut key = iter.next();
let mut val = iter.next();
while !key.is_none() && !val.is_none() {
......@@ -602,7 +610,7 @@ pub fn generate_dbus_arg(_item: TokenStream) -> TokenStream {
fn from_dbus(
x: Self::DBusType,
conn: Option<Arc<SyncConnection>>,
conn: Option<Arc<dbus::nonblock::SyncConnection>>,
remote: Option<BusName<'static>>,
disconnect_watcher: Option<Arc<Mutex<DisconnectWatcher>>>,
) -> Result<Self, Box<dyn Error>>
......@@ -627,7 +635,7 @@ pub fn generate_dbus_arg(_item: TokenStream) -> TokenStream {
fn from_dbus(
data: T,
_conn: Option<Arc<SyncConnection>>,
_conn: Option<Arc<dbus::nonblock::SyncConnection>>,
_remote: Option<BusName<'static>>,
_disconnect_watcher: Option<Arc<Mutex<DisconnectWatcher>>>,
) -> Result<T, Box<dyn Error>> {
......@@ -644,7 +652,7 @@ pub fn generate_dbus_arg(_item: TokenStream) -> TokenStream {
fn from_dbus(
data: Vec<T::DBusType>,
conn: Option<Arc<SyncConnection>>,
conn: Option<Arc<dbus::nonblock::SyncConnection>>,
remote: Option<BusName<'static>>,
disconnect_watcher: Option<Arc<Mutex<DisconnectWatcher>>>,
) -> Result<Vec<T>, Box<dyn Error>> {
......
use core::any::Any;
use dbus_macros::{dbus_propmap, generate_dbus_arg};
use dbus::arg::{Arg, ArgType, IterAppend, RefArg};
use dbus::Signature;
generate_dbus_arg!();
#[derive(Debug, Default, Clone, PartialEq)]
struct OtherStruct {
address: String,
}
#[dbus_propmap(OtherStruct)]
struct OtherStructDBus {
address: String,
}
#[derive(Debug, Default, Clone, PartialEq)]
struct SomeStruct {
name: String,
number: i32,
other_struct: OtherStruct,
bytes: Vec<u8>,
nested: Vec<Vec<String>>,
recursive: Vec<SomeStruct>,
}
#[dbus_propmap(SomeStruct)]
struct SomeStructDBus {
name: String,
number: i32,
other_struct: OtherStruct,
bytes: Vec<u8>,
nested: Vec<Vec<String>>,
recursive: Vec<SomeStruct>,
}
// Pretends to be a D-Bus dictionary.
#[derive(Debug)]
struct FakeDictionary {
items: Vec<(String, Box<dyn RefArg>)>,
}
impl RefArg for FakeDictionary {
fn arg_type(&self) -> ArgType {
todo!()
}
fn signature(&self) -> dbus::Signature<'static> {
todo!()
}
fn append(&self, _: &mut IterAppend<'_>) {
todo!()
}
fn as_any(&self) -> &(dyn Any + 'static) {
todo!()
}
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static) {
todo!()
}
fn box_clone(&self) -> Box<dyn RefArg + 'static> {
Box::new(FakeDictionary {
items: self.items.iter().map(|(k, v)| (k.clone(), v.box_clone())).collect(),
})
}
fn as_iter<'b>(&'b self) -> Option<Box<dyn Iterator<Item = &'b dyn RefArg> + 'b>> {
Some(Box::new(
self.items
.iter()
.flat_map(|(k, v)| vec![k as &dyn RefArg, v as &dyn RefArg].into_iter()),
))
}
}
impl Arg for FakeDictionary {
const ARG_TYPE: ArgType = ArgType::Array;
fn signature() -> dbus::Signature<'static> {
Signature::from("a{sv}")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dbus_propmap_error() {
let data_dbus = String::from("some data");
let result = <dbus::arg::PropMap as RefArgToRust>::ref_arg_to_rust(
&data_dbus,
String::from("Some Variable"),
);
assert!(result.is_err());
assert_eq!("Some Variable is not iterable", result.unwrap_err().to_string());
}
#[test]
fn test_dbus_propmap_success() {
let data_dbus = FakeDictionary {
items: vec![
(String::from("name"), Box::new(String::from("foo"))),
(String::from("number"), Box::new(100)),
(
String::from("other_struct"),
Box::new(FakeDictionary {
items: vec![(
String::from("address"),
Box::new(String::from("aa:bb:cc:dd:ee:ff")),
)],
}),
),
(String::from("bytes"), Box::new(vec![1 as u8, 2, 3])),
(
String::from("nested"),
Box::new(vec![
vec![
String::from("string a"),
String::from("string b"),
String::from("string c"),
],
vec![String::from("string 1"), String::from("string 2")],
]),
),
(
String::from("recursive"),
Box::new(vec![FakeDictionary {
items: vec![
(String::from("name"), Box::new(String::from("bar"))),
(String::from("number"), Box::new(200)),
(
String::from("other_struct"),
Box::new(FakeDictionary {
items: vec![(
String::from("address"),
Box::new(String::from("xx")),
)],
}),
),
(String::from("bytes"), Box::new(Vec::<u8>::new())),
(String::from("nested"), Box::new(Vec::<Vec<u8>>::new())),
(String::from("recursive"), Box::new(Vec::<FakeDictionary>::new())),
],
}]),
),
],
};
let result = <dbus::arg::PropMap as RefArgToRust>::ref_arg_to_rust(
&data_dbus,
String::from("Some Variable"),
);
assert!(result.is_ok());
let result = result.unwrap();
let result_struct = <SomeStruct as DBusArg>::from_dbus(result, None, None, None).unwrap();
let expected_struct = SomeStruct {
name: String::from("foo"),
number: 100,
other_struct: OtherStruct { address: String::from("aa:bb:cc:dd:ee:ff") },
bytes: vec![1, 2, 3],
nested: vec![
vec![String::from("string a"), String::from("string b"), String::from("string c")],
vec![String::from("string 1"), String::from("string 2")],
],
recursive: vec![SomeStruct {
name: String::from("bar"),
number: 200,
other_struct: OtherStruct { address: String::from("xx") },
bytes: vec![],
nested: vec![],
recursive: vec![],
}],
};
assert_eq!(expected_struct, result_struct);
}
}
use dbus::arg::RefArg;
use dbus::nonblock::SyncConnection;
use dbus::strings::Path;
use dbus_macros::{dbus_method, dbus_propmap, dbus_proxy_obj, generate_dbus_exporter};
use dbus_projection::DisconnectWatcher;
......
......@@ -3,7 +3,6 @@ use btstack::bluetooth_media::{IBluetoothMedia, IBluetoothMediaCallback};
use btstack::RPCProxy;
use dbus::arg::RefArg;
use dbus::nonblock::SyncConnection;
use dbus::strings::Path;
use dbus_macros::{dbus_method, dbus_propmap, dbus_proxy_obj, generate_dbus_exporter};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment