viaduct

Crates.ioviaduct
lib.rsviaduct
version0.4.0
sourcesrc
created_at2022-08-05 21:45:04.942274
updated_at2022-08-18 19:07:33.77175
descriptionA duplex communication channel between a parent and child process, using unnamed pipes
homepage
repositoryhttps://github.com/WilliamVenner/viaduct
max_upload_size
id639575
size91,326
William (WilliamVenner)

documentation

README

crates.io docs.rs license

Viaduct is a library for establishing a duplex communication channel between a parent and child process, using unnamed pipes.

Example

Shared library

#[derive(Serialize, Deserialize)]
pub enum ExampleRpc {
    Cow,
    Pig,
    Horse
}

#[derive(Serialize, Deserialize)]
pub enum ExampleRequest {
    DoAFrontflip,
    DoABackflip,
}

#[derive(Serialize, Deserialize, PartialEq, Eq)]
pub struct FrontflipError;

#[derive(Serialize, Deserialize, PartialEq, Eq)]
pub struct BackflipError;

Parent process

let child = std::process::Command::new("child.exe");
let ((tx, rx), mut child) = ViaductParent::new(child).unwrap().build().unwrap();

std::thread::spawn(move || {
    rx.run(
        |rpc: ExampleRpc| match rpc {
            ExampleRpc::Cow => println!("Moo"),
            ExampleRpc::Pig => println!("Oink"),
            ExampleRpc::Horse => println!("Neigh"),
        },

        |request: ExampleRequest, tx| match request {
            ExampleRequest::DoAFrontflip => {
                println!("Doing a frontflip!");
                tx.respond(Ok::<_, FrontflipError>(())).unwrap();
            },

            ExampleRequest::DoABackflip => {
                println!("Doing a backflip!");
                tx.respond(Ok::<_, BackflipError>(())).unwrap();
            },
        },
    ).unwrap();
});

tx.rpc(ExampleRpc::Cow).unwrap();
tx.rpc(ExampleRpc::Pig).unwrap();
tx.rpc(ExampleRpc::Horse).unwrap();

let response: Result<(), FrontflipError> = tx.request(ExampleRequest::DoAFrontflip).unwrap();
assert_eq!(response, Ok(()));

Child process

let (tx, rx) = unsafe { ViaductChild::new() }.unwrap();

std::thread::spawn(move || {
    rx.run(
        |rpc: ExampleRpc| match rpc {
            ExampleRpc::Cow => println!("Moo"),
            ExampleRpc::Pig => println!("Oink"),
            ExampleRpc::Horse => println!("Neigh"),
        },

        |request: ExampleRequest, tx| match request {
            ExampleRequest::DoAFrontflip => {
                println!("Doing a frontflip!");
                tx.respond(Ok::<_, FrontflipError>(())).unwrap();
            },

            ExampleRequest::DoABackflip => {
                println!("Doing a backflip!");
                tx.respond(Ok::<_, BackflipError>(())).unwrap();
            },
        },
    ).unwrap();
});

tx.rpc(ExampleRpc::Horse).unwrap();
tx.rpc(ExampleRpc::Pig).unwrap();
tx.rpc(ExampleRpc::Cow).unwrap();

let response: Result<(), BackflipError> = tx.request(ExampleRequest::DoABackflip).unwrap();
assert_eq!(response, Ok(()));

Use Cases

Viaduct was designed for separating user interface from application logic in a cross-platform manner.

For example, an application may want to run a GUI in a separate process from the application logic, for modularity or performance reasons.

Viaduct allows for applications like this to communicate between these processes in a natural way, without having to manually implement IPC machinery & synchronization.

Usage

Check out the documentation for usage information.

License

Viaduct is licensed under the MIT license or the Apache License v2.0, at your choice.

Commit count: 32

cargo fmt