38 releases (stable)
11.0.1 | Mar 9, 2021 |
---|---|
11.0.0 | Jun 3, 2020 |
10.0.0 | Nov 14, 2019 |
8.1.0 | May 15, 2019 |
0.4.0 | Mar 29, 2018 |
#639 in Operating systems
90,184 downloads per month
Used in 3 crates
92KB
2K
SLoC
varlink
The varlink crate provides support to implement client and server using the varlink protocol.
See http://varlink.org for more information about varlink.
More Info
- API Documentation
- Crate
- Example usage of this crate
lib.rs
:
Server and client support for the varlink protocol
Server
To create a varlink server in rust, place your varlink interface definition file in src/.
E.g. src/org.example.ping.varlink
:
interface org.example.ping
method Ping(ping: string) -> (pong: string)
Then create a build.rs
file in your project directory:
extern crate varlink_generator;
fn main() {
varlink_generator::cargo_build_tosource("src/org.example.ping.varlink",
/* rustfmt */ true);
}
For more code generation functions see the generator functions
.
Add to your Cargo.toml
:
[package]
build = "build.rs"
[build-dependencies]
varlink_generator = "<version>"
In your main.rs
you can then use:
mod org_example_ping;
and then implement the interface:
struct MyOrgExamplePing;
impl VarlinkInterface for MyOrgExamplePing {
fn ping(&self, call: &mut dyn Call_Ping, ping: String) -> Result<()> {
return call.reply(ping);
}
}
to implement the interface methods.
If your varlink method is called TestMethod
, the rust method to be implemented is called
test_method
. The first parameter is of type Call_TestMethod
, which has the method reply()
.
fn test_method(&self, call: &mut dyn Call_TestMethod, /* more arguments */) -> Result<()> {
/* ... */
return call.reply( /* more arguments */ );
}
A typical server creates a VarlinkService
and starts a server via varlink::listen
#
#
let args: Vec<_> = std::env::args().collect();
let myorgexampleping = MyOrgExamplePing;
let myorgexampleping_interface = org_example_ping::new(Box::new(myorgexampleping));
let service = varlink::VarlinkService::new(
"org.varlink",
"test service",
"0.1",
"http://varlink.org",
vec![
Box::new(myorgexampleping_interface),
// more interfaces ...
],
);
varlink::listen(service, &args[1],
&varlink::ListenConfig {
idle_timeout: 1,
..Default::default()
},
);
where args[1] would follow the varlink address specification.
Currently supported address URIs are:
- TCP
tcp:127.0.0.1:12345
hostname/IP address and port - UNIX socket
unix:/run/org.example.ftl
optional access;mode=0666
parameter - UNIX abstract namespace socket
unix:@org.example.ftl
(on Linux only)
Client
Setup your project, just like in the server case with a varlink file
and a build.rs
file.
In your main.rs
you can then use:
mod org_example_ping;
use org_example_ping;
let connection = Connection::with_address("unix:/tmp/org.example.ping").unwrap();
let mut ping_service = org_example_ping::VarlinkClient::new(connection);
let reply = ping_service.ping(String::from("Test")).call()?;
assert_eq!(String::from("Test"), reply.pong);
A connection can be established via the connection builder
functions.
The org_example_ping::VarlinkClient
implements org_example_ping::VarlinkClientInterface
,
which has all the varlink methods (names converted from camel case to lowercase snake case).
The PingString()
method would be named ping_string()
.
To iterate over a more
call
for reply in my_more_service.test_more(/* params */).more()? { /*...*/ }
The reply struct is placed in a structure named after the method with _Reply
appended.
So, the reply to the Ping()
method in our example is in a struct called Ping_Reply
.
Dependencies
~2–12MB
~150K SLoC