1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * rust-daemon
 * Core module, re-exports client and server components
 *
 * https://github.com/ryankurte/rust-daemon
 * Copyright 2018 Ryan Kurte
 */
extern crate libc;
extern crate users;

extern crate futures;

extern crate tokio;
extern crate tokio_io;
extern crate tokio_uds;
extern crate tokio_timer;

extern crate serde;
extern crate serde_json;

#[cfg(test)]
#[macro_use]
extern crate serde_derive;

extern crate tokio_serde_json_mirror as tokio_serde_json;

#[macro_use]
extern crate log;
extern crate uuid;


/// Client implements a daemon client (ie. command line utility)
pub mod client;
pub use client::Client;

/// Server implements a daemon server (ie. long running process)
pub mod server;
pub use server::Server;

/// Error implements errors returned by the daemon
pub mod error;
pub use error::DaemonError;

mod user;
pub use user::User;

#[cfg(test)]
mod tests {
    use std::env;
    use std::thread::sleep;
    use std::time::{Duration, Instant};
    use tokio::prelude::*;
    use tokio::{run, spawn};
    use {Client, Server};

    #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
    struct Test {
        text: String,
    }

    #[test]
    fn it_works() {
        let path = format!("{}/rust-daemon.sock", env::temp_dir().to_str().unwrap());
        println!("[TEST] Socket path: {}", path);

        let server_path = path.clone();
        let test = future::lazy(move || {
            println!("[TEST] Creating server");
            let mut server = Server::<Test, Test>::new(server_path).unwrap();

            println!("[TEST] Awaiting connect");
            let server_handle = server.incoming().unwrap()
                .for_each(move |r| {
                    let data = r.data();
                    println!("server incoming: {:?}", data);
                    r.send(data).wait().unwrap();
                    Ok(())
                }).map_err(|_e| ());
            spawn(server_handle);

            println!("[TEST] Creating client");
            let client = Client::<_, Test, Test>::new(path.clone()).unwrap();

            let (tx, rx) = client.split();

            println!("[TEST] Writing Data");
            let out = Test {
                text: "test text".to_owned(),
            };
            tx.send(out.clone()).wait().unwrap();

            sleep(Duration::from_secs(2));

            println!("[TEST] Reading Data");
            rx.map(|d| -> Result<(), ()> {
                println!("client incoming: {:?}", d);
                assert_eq!(d, out);
                Ok(())
            }).wait()
            .next();

            server.close();

            Ok(())
        }).then(|_: Result<(), ()>| -> Result<(), ()> {
            println!("[TEST] Done");
            
            Ok(())
        });

        run(test);
    }
}