Created
June 28, 2019 23:31
-
-
Save neonphog/f98d31688f23e4b47c2a8c6b974f8923 to your computer and use it in GitHub Desktop.
Rust Capnp with Json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* FROM CAPNP SCHEMA: | |
| struct Message { | |
| union { | |
| msgError @0 :MsgError; | |
| } | |
| struct MsgError { | |
| errorCode @0 :ErrorCode; | |
| errorText @1 :Text; | |
| enum ErrorCode { | |
| unknown @0; | |
| invalidChannelId @1; | |
| } | |
| } | |
| } | |
| */ | |
| extern crate capnp; | |
| extern crate serde; | |
| #[macro_use] | |
| extern crate serde_derive; | |
| extern crate serde_json; | |
| pub mod p2p_capnp; | |
| use p2p_capnp::message; | |
| use p2p_capnp::message::msg_error; | |
| trait FromCapnp<I, O> { | |
| fn from_capnp(i: I) -> O; | |
| } | |
| trait ToCapnp<W> { | |
| fn to_capnp(&self, w: W); | |
| } | |
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] | |
| pub enum ErrorCode { | |
| Unknown = 0, | |
| InvalidChannelId = 1, | |
| } | |
| impl FromCapnp<msg_error::ErrorCode, ErrorCode> for ErrorCode { | |
| fn from_capnp(i: msg_error::ErrorCode) -> ErrorCode { | |
| return match i as u16 { | |
| 1 => ErrorCode::InvalidChannelId, | |
| _ => ErrorCode::Unknown, | |
| }; | |
| } | |
| } | |
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] | |
| pub struct MsgError { | |
| pub error_code: ErrorCode, | |
| pub error_text: String, | |
| } | |
| impl<'a> FromCapnp<msg_error::Reader<'a>, MsgError> for MsgError { | |
| fn from_capnp(i: msg_error::Reader) -> MsgError { | |
| return MsgError { | |
| error_code: ErrorCode::from_capnp(i.get_error_code().unwrap()), | |
| error_text: i.get_error_text().unwrap().to_string(), | |
| } | |
| } | |
| } | |
| impl<'a> ToCapnp<msg_error::Builder<'a>> for MsgError { | |
| fn to_capnp(&self, mut w: msg_error::Builder) { | |
| w.set_error_code(match self.error_code { | |
| ErrorCode::InvalidChannelId => msg_error::ErrorCode::InvalidChannelId, | |
| _ => msg_error::ErrorCode::Unknown, | |
| }); | |
| w.set_error_text(&self.error_text); | |
| } | |
| } | |
| #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] | |
| pub enum Message { | |
| Unknown, | |
| MsgError(MsgError), | |
| } | |
| impl<'a> FromCapnp<message::Reader<'a>, Message> for Message { | |
| fn from_capnp(i: message::Reader) -> Message { | |
| match i.which().unwrap() { | |
| message::Which::MsgError(err) => { | |
| return Message::MsgError(MsgError::from_capnp(err.unwrap())); | |
| } | |
| _ => {} | |
| } | |
| Message::Unknown | |
| } | |
| } | |
| impl<'a> ToCapnp<message::Builder<'a>> for Message { | |
| fn to_capnp(&self, w: message::Builder) { | |
| match self { | |
| Message::MsgError(err) => { | |
| err.to_capnp(w.init_msg_error()); | |
| } | |
| _ => {} | |
| } | |
| } | |
| } | |
| fn main() { | |
| let msg = Message::MsgError(MsgError { | |
| error_code: ErrorCode::InvalidChannelId, | |
| error_text: "try encoding this".to_string(), | |
| }); | |
| let mut data: Vec<u8> = Vec::with_capacity(4069); | |
| { | |
| let mut message = capnp::message::Builder::new_default(); | |
| msg.to_capnp(message.init_root::<message::Builder>()); | |
| capnp::serialize_packed::write_message(&mut data, &message).unwrap(); | |
| } | |
| println!("generated bytes: {:?}", data.as_slice()); | |
| let parsed = { | |
| let reader = capnp::serialize_packed::read_message( | |
| &mut std::io::Cursor::new(&data), | |
| capnp::message::ReaderOptions::new()).unwrap(); | |
| let message = reader.get_root::<message::Reader>().unwrap(); | |
| Message::from_capnp(message) | |
| }; | |
| println!("parsed: {:?}", parsed); | |
| let j = serde_json::to_string_pretty(&msg).unwrap(); | |
| println!("as_json: {}", j); | |
| let jparsed: Message = serde_json::from_str(&j).unwrap(); | |
| println!("from_json: {:?}", jparsed); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment