use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use zlink::{
Server,
introspect::{self, CustomType},
tokio::unix::{bind, connect},
};
#[test_log::test(tokio::test(flavor = "multi_thread"))]
async fn underscore_prefixed_params() -> Result<(), Box<dyn std::error::Error>> {
let dir = tempfile::tempdir()?;
let socket_path = dir.path().join("test.sock");
let listener = bind(&socket_path).unwrap();
let service = Launcher;
let server = Server::new(listener, service);
tokio::select! {
res = server.run() => res?,
res = run_client(&socket_path) => res?,
}
Ok(())
}
async fn run_client(socket_path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
let mut conn = connect(socket_path).await?;
let reply = conn
.uninstall("org.example.Foo.desktop", HashMap::new())
.await?
.unwrap();
assert_eq!(reply.desktop_file_id, "org.example.Foo.desktop");
let reply = conn
.launch("org.example.Bar.desktop", HashMap::new())
.await?
.unwrap();
assert_eq!(reply.desktop_file_id, "org.example.Bar.desktop");
{
use zlink::varlink_service::Proxy as VarlinkProxy;
let desc = conn
.get_interface_description("org.example.launcher")
.await?
.unwrap();
let interface = desc.parse()?;
for name in ["Uninstall", "Launch"] {
let method = interface
.methods()
.find(|m| m.name() == name)
.expect("method not found in introspection data");
let input_names: Vec<_> = method.inputs().map(|f| f.name()).collect();
assert_eq!(input_names.as_slice(), &["desktop_file_id", "options"]);
}
}
Ok(())
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, CustomType)]
struct Launched {
desktop_file_id: String,
}
#[derive(Debug, Clone, PartialEq, zlink::ReplyError, introspect::ReplyError)]
#[zlink(interface = "org.example.launcher")]
enum LauncherError {
NotFound,
}
struct Launcher;
#[zlink::service(types = [Launched])]
impl<Sock> Launcher {
#[zlink(interface = "org.example.launcher")]
async fn uninstall(
&mut self,
desktop_file_id: String,
#[zlink(rename = "options")] _options: HashMap<String, String>,
) -> Result<Launched, LauncherError> {
Ok(Launched { desktop_file_id })
}
async fn launch(
&mut self,
desktop_file_id: String,
#[zlink(rename = "options")] _options: HashMap<String, String>,
#[zlink(connection)] _conn: &mut zlink::Connection<Sock>,
) -> Result<Launched, LauncherError> {
Ok(Launched { desktop_file_id })
}
}
#[zlink::proxy("org.example.launcher")]
trait LauncherProxy {
async fn uninstall(
&mut self,
desktop_file_id: &str,
options: HashMap<String, String>,
) -> zlink::Result<Result<Launched, LauncherError>>;
async fn launch(
&mut self,
desktop_file_id: &str,
options: HashMap<String, String>,
) -> zlink::Result<Result<Launched, LauncherError>>;
}