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
//! A library to make native messaging even easier than it already is. //! //! Typically you'd use this in a loop, reading a message in and writing a //! message out until there are none left to read. Perhaps something like this: //! //! ```rust,no_run //! # extern crate webext; //! # #[macro_use] //! # extern crate serde_derive; //! # fn main() { //! # //! #[derive(Deserialize)] //! struct Input { n: usize } //! //! #[derive(Serialize)] //! struct Output { n: usize } //! //! // An extension that just adds one to the input number `n`. //! //! while let Some(msg) = webext::read::<Input>() { //! let inp = msg.unwrap(); //! let out = Output { n: inp.n + 1 }; //! webext::write(&out).unwrap(); //! } //! # //! # } //! ``` //! //! # Serde //! //! I strongly recommend that you use this with `serde_derive` so that you can //! use your own structs for input and output. Alternatively, you can use the //! `Json` type, but that's a lot more annoying to deal with. My favorite enum //! attributes are `#[serde(tag = "type", rename_all = "snake_case")]`. extern crate byteorder; extern crate serde; extern crate serde_json as json; use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; use serde::{Deserialize, Serialize}; use std::io::{self, Read, Write}; use io::ErrorKind::{BrokenPipe, UnexpectedEof}; /// A type that can encode to and decode from any JSON string. pub type Json = json::Value; /// Read a message from standard input. pub fn read<D: for<'a> Deserialize<'a>>() -> Option<io::Result<D>> { let stdin = io::stdin(); let mut stdin = stdin.lock(); let len = match stdin.read_u32::<NativeEndian>() { Ok(len) => len, Err(e) => return if e.kind() == BrokenPipe || e.kind() == UnexpectedEof { None } else { Some(Err(e.into())) }, }; Some(json::from_reader((&mut stdin).take(len as _)).map_err(Into::into)) } /// Write a message to standard output. pub fn write<S: Serialize>(msg: &S) -> io::Result<()> { let stdout = io::stdout(); let mut stdout = stdout.lock(); let msg = json::to_vec(msg)?; stdout.write_u32::<NativeEndian>(msg.len() as _)?; stdout.write_all(&msg)?; Ok(()) }