webextension_protocol/
lib.rs

1extern crate byteorder;
2
3use std::str;
4use std::io;
5use std::io::Stdin;
6use std::io::Stdout;
7use std::io::Read;
8use std::io::Error;
9use std::io::Write;
10use std::io::Cursor;
11use std::fs::File;
12use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
13
14// source: http://stackoverflow.com/a/27590832/1877270
15#[macro_export]
16macro_rules! println_stderr(
17    ($($arg:tt)*) => { {
18        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
19        r.expect("failed printing to stderr");
20    } }
21);
22
23pub enum Input {
24    File(File),
25    Stdin(Stdin),
26}
27
28impl Read for Input {
29    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
30        match *self {
31            Input::File(ref mut file) => file.read(buf),
32            Input::Stdin(ref mut stdin) => stdin.read(buf),
33        }
34    }
35}
36
37pub fn read(mut input: Input) -> Result<String, Error> {
38    // Read JSON size
39    let mut buffer = [0; 4];
40    match input.read_exact(&mut buffer) {
41        Ok(_) => {},
42        Err(e) => {
43            println_stderr!("Noting more to read - exiting");
44            return Err(e);
45        },
46    }
47    let mut buf = Cursor::new(&buffer);
48    let size = buf.read_u32::<LittleEndian>().unwrap();
49    println_stderr!("going to read {} bytes", size);
50
51    // Read JSON
52    let mut data_buffer = vec![0u8; size as usize];
53    input.read_exact(&mut data_buffer).expect("cannot read data");
54    let string = str::from_utf8(&data_buffer).unwrap().to_string();
55    println_stderr!("received: {}", string);
56
57    return Ok(string);
58}
59
60pub fn read_stdin() -> Result<String, Error> {
61    let f = Input::Stdin(io::stdin());
62    return read(f);
63}
64
65pub enum Output {
66    File(File),
67    Stdout(Stdout),
68}
69
70impl Write for Output {
71    fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
72        match *self {
73            Output::File(ref mut file) => file.write(buf),
74            Output::Stdout(ref mut stdout) => stdout.write(buf),
75        }
76    }
77
78    fn flush(&mut self) -> Result<(), Error> {
79        match *self {
80            Output::File(ref mut file) => file.flush(),
81            Output::Stdout(ref mut stdout) => stdout.flush(),
82        }
83    }
84}
85
86pub fn write(mut output: Output, message: String) {
87    let size = message.capacity();
88    let mut sizeVector = vec![];
89    sizeVector.write_u32::<LittleEndian>(size as u32).unwrap();
90    output.write(&sizeVector);
91    output.write(&message.into_bytes());
92    output.flush();
93}
94
95pub fn write_stdout(message: String) {
96    let output = Output::Stdout(io::stdout());
97    write(output, message.to_string());
98}