diff --git a/marketdata.capnp b/marketdata.capnp index 9b601cf..d53ab51 100644 --- a/marketdata.capnp +++ b/marketdata.capnp @@ -1,7 +1,12 @@ @0x9b88118c58e937dc; +struct MultiMessage { + seqNo @0 :UInt64; + messages @1 :List(Message); +} + struct Message { - tsNanos @0 :Int64; + ts @0 :UInt64; symbol @1 :Text; union { diff --git a/marketdata.fbs b/marketdata.fbs index 29f80ed..9f74475 100644 --- a/marketdata.fbs +++ b/marketdata.fbs @@ -26,3 +26,8 @@ table Message { symbol:string; body:MessageBody; } + +table MultiMessage { + seq_no:uint64; + messages:[Message]; +} diff --git a/src/main.rs b/src/main.rs index 60d14ce..f7498e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,6 @@ pub mod marketdata_capnp; pub mod marketdata_generated; // Flatbuffers -pub mod marketdata_custom; - fn main() { println!("Hello, world!"); } diff --git a/src/marketdata_capnp.rs b/src/marketdata_capnp.rs index d7a8e79..a8773f2 100644 --- a/src/marketdata_capnp.rs +++ b/src/marketdata_capnp.rs @@ -3,6 +3,153 @@ // source: marketdata.capnp +pub mod multi_message { + #[derive(Copy, Clone)] + pub struct Owned; + impl <'a> ::capnp::traits::Owned<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl <'a> ::capnp::traits::OwnedStruct<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + #[derive(Clone, Copy)] + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructReader<'a> for Reader<'a,> { + fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,> { + Reader { reader: reader, } + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::std::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result> { + ::std::result::Result::Ok(::capnp::traits::FromStructReader::new(reader.get_struct(default)?)) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<> { + Reader { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_seq_no(self) -> u64 { + self.reader.get_data_field::(0) + } + #[inline] + pub fn get_messages(self) -> ::capnp::Result<::capnp::struct_list::Reader<'a,crate::marketdata_capnp::message::Owned>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::std::option::Option::None) + } + pub fn has_messages(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + #[inline] + fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE } + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,> { + fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, > { + Builder { builder: builder, } + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,> { + ::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE)) + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::std::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result> { + ::std::result::Result::Ok(::capnp::traits::FromStructBuilder::new(builder.get_struct(_private::STRUCT_SIZE, default)?)) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder> for Reader<'a,> { + fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,>, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + pub fn reborrow(&mut self) -> Builder<> { + Builder { .. *self } + } + pub fn reborrow_as_reader(&self) -> Reader<> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.into_reader().total_size() + } + #[inline] + pub fn get_seq_no(self) -> u64 { + self.builder.get_data_field::(0) + } + #[inline] + pub fn set_seq_no(&mut self, value: u64) { + self.builder.set_data_field::(0, value); + } + #[inline] + pub fn get_messages(self) -> ::capnp::Result<::capnp::struct_list::Builder<'a,crate::marketdata_capnp::message::Owned>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::std::option::Option::None) + } + #[inline] + pub fn set_messages(&mut self, value: ::capnp::struct_list::Reader<'a,crate::marketdata_capnp::message::Owned>) -> ::capnp::Result<()> { + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(0), value, false) + } + #[inline] + pub fn init_messages(self, size: u32) -> ::capnp::struct_list::Builder<'a,crate::marketdata_capnp::message::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), size) + } + pub fn has_messages(&self) -> bool { + !self.builder.get_pointer_field(0).is_null() + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline { + Pipeline { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + use capnp::private::layout; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 1 }; + pub const TYPE_ID: u64 = 0xd13b_1bd4_36e1_ca9f; + } +} + pub mod message { pub use self::Which::{Trade,Quote}; @@ -52,8 +199,8 @@ pub mod message { self.reader.total_size() } #[inline] - pub fn get_ts_nanos(self) -> i64 { - self.reader.get_data_field::(0) + pub fn get_ts(self) -> u64 { + self.reader.get_data_field::(0) } #[inline] pub fn get_symbol(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { @@ -137,12 +284,12 @@ pub mod message { self.builder.into_reader().total_size() } #[inline] - pub fn get_ts_nanos(self) -> i64 { - self.builder.get_data_field::(0) + pub fn get_ts(self) -> u64 { + self.builder.get_data_field::(0) } #[inline] - pub fn set_ts_nanos(&mut self, value: i64) { - self.builder.set_data_field::(0, value); + pub fn set_ts(&mut self, value: u64) { + self.builder.set_data_field::(0, value); } #[inline] pub fn get_symbol(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { diff --git a/src/marketdata_custom.rs b/src/marketdata_custom.rs deleted file mode 100644 index c135c9e..0000000 --- a/src/marketdata_custom.rs +++ /dev/null @@ -1,46 +0,0 @@ -// This is hand-written code to act as proof-of-concept -// for a more complex schema generator. Theoretically, the -// schema file that would be used to generate the code below -// looks something like this (influenced by Kaitai Struct): -// -// seq: -// - id: ts_nanos -// type: u64 -// - id: symbol -// type: str -// - id: msg_type -// type: u8 -// enum: msg_type -// - id: msg_body -// type: -// switch-on: msg_type -// cases: -// msg_type::trade: trade -// msg_type::level_update: level_update -// enums: -// msg_type: -// 0: trade -// 1: level_update -// -// side: -// 0: buy -// 1: sell -// -// types: -// trade: -// seq: -// - id: price -// type: u64 -// - id: size -// type: u32 -// level_update: -// seq: -// - id: price -// type: u64 -// - id: size -// type: u32 -// - id: flags -// type: u8 -// - id: side -// type: u8 -// enum: side diff --git a/src/marketdata_generated.rs b/src/marketdata_generated.rs index 7ba1fd9..e88a118 100644 --- a/src/marketdata_generated.rs +++ b/src/marketdata_generated.rs @@ -473,5 +473,93 @@ impl<'a: 'b, 'b> MessageBuilder<'a, 'b> { } } +pub enum MultiMessageOffset {} +#[derive(Copy, Clone, Debug, PartialEq)] + +pub struct MultiMessage<'a> { + pub _tab: flatbuffers::Table<'a>, +} + +impl<'a> flatbuffers::Follow<'a> for MultiMessage<'a> { + type Inner = MultiMessage<'a>; + #[inline] + fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { + Self { + _tab: flatbuffers::Table { buf: buf, loc: loc }, + } + } +} + +impl<'a> MultiMessage<'a> { + #[inline] + pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self { + MultiMessage { + _tab: table, + } + } + #[allow(unused_mut)] + pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>( + _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>, + args: &'args MultiMessageArgs<'args>) -> flatbuffers::WIPOffset> { + let mut builder = MultiMessageBuilder::new(_fbb); + builder.add_seq_no(args.seq_no); + if let Some(x) = args.messages { builder.add_messages(x); } + builder.finish() + } + + pub const VT_SEQ_NO: flatbuffers::VOffsetT = 4; + pub const VT_MESSAGES: flatbuffers::VOffsetT = 6; + + #[inline] + pub fn seq_no(&self) -> u64 { + self._tab.get::(MultiMessage::VT_SEQ_NO, Some(0)).unwrap() + } + #[inline] + pub fn messages(&self) -> Option>>> { + self._tab.get::>>>>(MultiMessage::VT_MESSAGES, None) + } +} + +pub struct MultiMessageArgs<'a> { + pub seq_no: u64, + pub messages: Option>>>>, +} +impl<'a> Default for MultiMessageArgs<'a> { + #[inline] + fn default() -> Self { + MultiMessageArgs { + seq_no: 0, + messages: None, + } + } +} +pub struct MultiMessageBuilder<'a: 'b, 'b> { + fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>, + start_: flatbuffers::WIPOffset, +} +impl<'a: 'b, 'b> MultiMessageBuilder<'a, 'b> { + #[inline] + pub fn add_seq_no(&mut self, seq_no: u64) { + self.fbb_.push_slot::(MultiMessage::VT_SEQ_NO, seq_no, 0); + } + #[inline] + pub fn add_messages(&mut self, messages: flatbuffers::WIPOffset>>>) { + self.fbb_.push_slot_always::>(MultiMessage::VT_MESSAGES, messages); + } + #[inline] + pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> MultiMessageBuilder<'a, 'b> { + let start = _fbb.start_table(); + MultiMessageBuilder { + fbb_: _fbb, + start_: start, + } + } + #[inline] + pub fn finish(self) -> flatbuffers::WIPOffset> { + let o = self.fbb_.end_table(self.start_); + flatbuffers::WIPOffset::new(o.value()) + } +} + } // pub mod MdShootout