use serde_derive::{Deserialize, Serialize}; use std::io::BufRead; use std::sync::{Arc, RwLock}; use varlink::{self, CallTrait}; #[allow(dead_code)] #[derive(Clone, PartialEq, Debug)] #[allow(clippy::enum_variant_names)] pub enum ErrorKind { Varlink_Error, VarlinkReply_Error, ErrorBar(Option), ErrorFoo(Option), } impl ::std::fmt::Display for ErrorKind { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { match self { ErrorKind::Varlink_Error => write!(f, "Varlink Error"), ErrorKind::VarlinkReply_Error => write!(f, "Varlink error reply"), ErrorKind::ErrorBar(v) => write!(f, "org.example.complex.ErrorBar: {:#?}", v), ErrorKind::ErrorFoo(v) => write!(f, "org.example.complex.ErrorFoo: {:#?}", v), } } } pub struct Error( pub ErrorKind, pub Option>, pub Option<&'static str>, ); impl Error { #[allow(dead_code)] pub fn kind(&self) -> &ErrorKind { &self.0 } } impl From for Error { fn from(e: ErrorKind) -> Self { Error(e, None, None) } } impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { self.1 .as_ref() .map(|e| e.as_ref() as &(dyn std::error::Error + 'static)) } } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { std::fmt::Display::fmt(&self.0, f) } } impl std::fmt::Debug for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { use std::error::Error as StdError; if let Some(ref o) = self.2 { std::fmt::Display::fmt(o, f)?; } std::fmt::Debug::fmt(&self.0, f)?; if let Some(e) = self.source() { std::fmt::Display::fmt("\nCaused by:\n", f)?; std::fmt::Debug::fmt(&e, f)?; } Ok(()) } } #[allow(dead_code)] pub type Result = std::result::Result; impl From for Error { fn from(e: varlink::Error) -> Self { match e.kind() { varlink::ErrorKind::VarlinkErrorReply(r) => Error( ErrorKind::from(r), Some(Box::from(e)), Some(concat!(file!(), ":", line!(), ": ")), ), _ => Error( ErrorKind::Varlink_Error, Some(Box::from(e)), Some(concat!(file!(), ":", line!(), ": ")), ), } } } #[allow(dead_code)] impl Error { pub fn source_varlink_kind(&self) -> Option<&varlink::ErrorKind> { use std::error::Error as StdError; let mut s: &dyn StdError = self; while let Some(c) = s.source() { let k = self .source() .and_then(|e| e.downcast_ref::()) .map(|e| e.kind()); if k.is_some() { return k; } s = c; } None } } impl From<&varlink::Reply> for ErrorKind { #[allow(unused_variables)] fn from(e: &varlink::Reply) -> Self { match e { varlink::Reply { error: Some(ref t), .. } if t == "org.example.complex.ErrorBar" => match e { varlink::Reply { parameters: Some(p), .. } => match serde_json::from_value(p.clone()) { Ok(v) => ErrorKind::ErrorBar(v), Err(_) => ErrorKind::ErrorBar(None), }, _ => ErrorKind::ErrorBar(None), }, varlink::Reply { error: Some(ref t), .. } if t == "org.example.complex.ErrorFoo" => match e { varlink::Reply { parameters: Some(p), .. } => match serde_json::from_value(p.clone()) { Ok(v) => ErrorKind::ErrorFoo(v), Err(_) => ErrorKind::ErrorFoo(None), }, _ => ErrorKind::ErrorFoo(None), }, _ => ErrorKind::VarlinkReply_Error, } } } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct r#ErrorFoo_Args_enum { pub r#b: bool, pub r#c: i64, pub r#interface: Interface, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum r#ErrorFoo_Args_bar { r#type, r#enum, r#int, r#bool, r#string, r#if, r#let, } pub trait VarlinkCallError: varlink::CallTrait { fn reply_error_bar(&mut self) -> varlink::Result<()> { self.reply_struct(varlink::Reply::error("org.example.complex.ErrorBar", None)) } fn reply_error_foo( &mut self, r#enum: ErrorFoo_Args_enum, r#foo: TypeFoo, r#bar: ErrorFoo_Args_bar, r#interface: Interface, ) -> varlink::Result<()> { self.reply_struct(varlink::Reply::error( "org.example.complex.ErrorFoo", Some( serde_json::to_value(ErrorFoo_Args { r#enum, r#foo, r#bar, r#interface, }) .map_err(varlink::map_context!())?, ), )) } } impl<'a> VarlinkCallError for varlink::Call<'a> {} #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum r#Enum { r#enum, r#b, r#c, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum r#Interface { r#interface, r#b, r#c, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum r#Type { r#type, r#b, r#c, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum r#TypeEnum { r#type, r#b, r#c, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum r#TypeFoo_enum { r#foo, r#bar, r#baz, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct r#TypeFoo_anon_baz { pub r#a: i64, pub r#b: i64, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct r#TypeFoo_anon { pub r#foo: bool, pub r#bar: i64, pub r#baz: Vec, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct r#TypeFoo { pub r#bool: bool, pub r#int: i64, pub r#float: f64, pub r#string: String, pub r#enum: Option>>, pub r#type: Option, pub r#anon: TypeFoo_anon, pub r#object: serde_json::Value, pub r#stringset: varlink::StringHashSet, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct ErrorBar_Args {} #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct r#ErrorFoo_Args_enum { pub r#b: bool, pub r#c: i64, pub r#interface: Interface, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum r#ErrorFoo_Args_bar { r#type, r#enum, r#int, r#bool, r#string, r#if, r#let, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct ErrorFoo_Args { pub r#enum: ErrorFoo_Args_enum, pub r#foo: TypeFoo, pub r#bar: ErrorFoo_Args_bar, pub r#interface: Interface, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct Bar_Reply {} impl varlink::VarlinkReply for Bar_Reply {} #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct Bar_Args {} pub trait Call_Bar: VarlinkCallError { fn reply(&mut self) -> varlink::Result<()> { self.reply_struct(varlink::Reply::parameters(None)) } } impl<'a> Call_Bar for varlink::Call<'a> {} #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct r#Foo_Args_enum { pub r#b: bool, pub r#c: i64, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct r#Foo_Reply_a { pub r#b: bool, pub r#c: i64, } #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct Foo_Reply { pub r#a: Vec, pub r#foo: TypeFoo, pub r#interface: Interface, } impl varlink::VarlinkReply for Foo_Reply {} #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct Foo_Args { pub r#enum: Foo_Args_enum, pub r#foo: TypeFoo, pub r#interface: Interface, } pub trait Call_Foo: VarlinkCallError { fn reply( &mut self, r#a: Vec, r#foo: TypeFoo, r#interface: Interface, ) -> varlink::Result<()> { self.reply_struct( Foo_Reply { r#a, r#foo, r#interface, } .into(), ) } } impl<'a> Call_Foo for varlink::Call<'a> {} pub trait VarlinkInterface { fn bar(&self, call: &mut dyn Call_Bar) -> varlink::Result<()>; fn foo( &self, call: &mut dyn Call_Foo, r#enum: Foo_Args_enum, r#foo: TypeFoo, r#interface: Interface, ) -> varlink::Result<()>; fn call_upgraded( &self, _call: &mut varlink::Call, _bufreader: &mut dyn BufRead, ) -> varlink::Result> { Ok(Vec::new()) } } pub trait VarlinkClientInterface { fn bar(&mut self) -> varlink::MethodCall; fn foo( &mut self, r#enum: Foo_Args_enum, r#foo: TypeFoo, r#interface: Interface, ) -> varlink::MethodCall; } #[allow(dead_code)] pub struct VarlinkClient { connection: Arc>, } impl VarlinkClient { #[allow(dead_code)] pub fn new(connection: Arc>) -> Self { VarlinkClient { connection } } } impl VarlinkClientInterface for VarlinkClient { fn bar(&mut self) -> varlink::MethodCall { varlink::MethodCall::::new( self.connection.clone(), "org.example.complex.Bar", Bar_Args {}, ) } fn foo( &mut self, r#enum: Foo_Args_enum, r#foo: TypeFoo, r#interface: Interface, ) -> varlink::MethodCall { varlink::MethodCall::::new( self.connection.clone(), "org.example.complex.Foo", Foo_Args { r#enum, r#foo, r#interface, }, ) } } #[allow(dead_code)] pub struct VarlinkInterfaceProxy { inner: Box, } #[allow(dead_code)] pub fn new(inner: Box) -> VarlinkInterfaceProxy { VarlinkInterfaceProxy { inner } } impl varlink::Interface for VarlinkInterfaceProxy { fn get_description(&self) -> &'static str { "interface org.example.complex\n\ntype Enum (enum, b, c)\n\ntype Type (type, b, c)\n\ntype TypeEnum (type, b, c)\n\ntype Interface (interface, b, c)\n\ntype TypeFoo (\n bool: bool,\n int: int,\n float: float,\n string: string,\n enum: ?[string]?(foo, bar, baz),\n type: ?TypeEnum,\n anon: (\n foo: bool,\n bar: int,\n baz: [](a: int, b: int)\n ),\n object: object,\n stringset: [string]()\n)\n\nmethod Foo(\n enum: (b: bool, c: int),\n foo: TypeFoo,\n interface: Interface\n) -> (\n a: [](b: bool, c: int),\n foo: TypeFoo,\n interface: Interface\n)\n\nmethod Bar() -> ()\n\nerror ErrorFoo (\n enum: (\n b: bool,\n c: int,\n interface: Interface\n ),\n foo: TypeFoo,\n bar: (type, enum, int, bool, string, if, let),\n interface: Interface\n)\n\nerror ErrorBar ()\n" } fn get_name(&self) -> &'static str { "org.example.complex" } fn call_upgraded( &self, call: &mut varlink::Call, bufreader: &mut dyn BufRead, ) -> varlink::Result> { self.inner.call_upgraded(call, bufreader) } fn call(&self, call: &mut varlink::Call) -> varlink::Result<()> { let req = call.request.unwrap(); match req.method.as_ref() { "org.example.complex.Bar" => self.inner.bar(call as &mut dyn Call_Bar), "org.example.complex.Foo" => { if let Some(args) = req.parameters.clone() { let args: Foo_Args = match serde_json::from_value(args) { Ok(v) => v, Err(e) => { let es = format!("{}", e); let _ = call.reply_invalid_parameter(es.clone()); return Err(varlink::context!(varlink::ErrorKind::SerdeJsonDe(es))); } }; self.inner.foo( call as &mut dyn Call_Foo, args.r#enum, args.r#foo, args.r#interface, ) } else { call.reply_invalid_parameter("parameters".into()) } } m => call.reply_method_not_found(String::from(m)), } } }