diff --git a/Cargo.lock b/Cargo.lock
index 94efbdf..f01f6b6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,25 @@
# It is not intended for manual editing.
version = 3
+[[package]]
+name = "capnp"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18eca1b9aca7e3623dda158213b1b79c1e5c4293fbbf0ead6b9ed28a1763bbff"
+
+[[package]]
+name = "capnpc"
+version = "0.16.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b45a0c0b3fec59ba52fc3bb90ba34cb6444e20691faa07be1dabb80660e4ad0"
+dependencies = [
+ "capnp",
+]
+
[[package]]
name = "maple-chat"
version = "0.1.0"
+dependencies = [
+ "capnp",
+ "capnpc",
+]
diff --git a/Cargo.toml b/Cargo.toml
index 6c1efb5..f327d1c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,7 +2,13 @@
name = "maple-chat"
version = "0.1.0"
edition = "2021"
+build = "src/build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+capnp = "0.16"
+
+[build-dependencies]
+capnpc = "0.16"
+
diff --git a/src/build.rs b/src/build.rs
new file mode 100644
index 0000000..c1d72aa
--- /dev/null
+++ b/src/build.rs
@@ -0,0 +1,10 @@
+extern crate capnpc;
+
+fn main() {
+ capnpc::CompilerCommand::new()
+ .output_path("src/schema/")
+ .src_prefix("src/schema/")
+ .file("src/schema/protocol.capnp")
+ .run()
+ .unwrap();
+}
diff --git a/src/main.rs b/src/main.rs
index 5ad14bf..54ad54a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,4 @@
+use capnp::any_pointer::Builder;
//Maple Chat, A simple chat app made with cap'n proto
//Copyright (C) 2023 Roux Pupo
//
@@ -13,7 +14,8 @@
//
//You should have received a copy of the GNU Affero General Public License
//along with this program. If not, see .
+use capnp::*;
+
fn main() {
- println!("Hello, world!");
}
diff --git a/src/schema/protocol.capnp b/src/schema/protocol.capnp
new file mode 100644
index 0000000..2fb5f6d
--- /dev/null
+++ b/src/schema/protocol.capnp
@@ -0,0 +1,12 @@
+@0xd93f69a809989ffc;
+struct User {
+ name @0 :Text;
+ age @1 :UInt8;
+}
+
+struct Message {
+ sender @0: User;
+ reciever @1: List(User);
+ content @2: Text;
+ time @3: Int64;
+}
diff --git a/src/schema/protocol_capnp.rs b/src/schema/protocol_capnp.rs
new file mode 100644
index 0000000..4b6cf1d
--- /dev/null
+++ b/src/schema/protocol_capnp.rs
@@ -0,0 +1,481 @@
+// @generated by the capnpc-rust plugin to the Cap'n Proto schema compiler.
+// DO NOT EDIT.
+// source: protocol.capnp
+
+pub mod user {
+ #[derive(Copy, Clone)]
+ pub struct Owned(());
+ impl ::capnp::traits::Owned for Owned {
+ type Reader<'a> = Reader<'a>;
+ type Builder<'a> = Builder<'a>;
+ }
+ impl ::capnp::traits::OwnedStruct for Owned {
+ type Reader<'a> = Reader<'a>;
+ type Builder<'a> = 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> {
+ const TYPE_ID: u64 = _private::TYPE_ID;
+ }
+ impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> {
+ fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self {
+ Self { reader }
+ }
+ }
+
+ impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> {
+ fn get_from_pointer(
+ reader: &::capnp::private::layout::PointerReader<'a>,
+ default: ::core::option::Option<&'a [capnp::Word]>,
+ ) -> ::capnp::Result {
+ ::core::result::Result::Ok(reader.get_struct(default)?.into())
+ }
+ }
+
+ 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<'_> {
+ Self { ..*self }
+ }
+
+ pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
+ self.reader.total_size()
+ }
+ #[inline]
+ pub fn get_name(self) -> ::capnp::Result<::capnp::text::Reader<'a>> {
+ ::capnp::traits::FromPointerReader::get_from_pointer(
+ &self.reader.get_pointer_field(0),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn has_name(&self) -> bool {
+ !self.reader.get_pointer_field(0).is_null()
+ }
+ #[inline]
+ pub fn get_age(self) -> u8 {
+ self.reader.get_data_field::(0)
+ }
+ }
+
+ pub struct Builder<'a> {
+ builder: ::capnp::private::layout::StructBuilder<'a>,
+ }
+ impl<'a> ::capnp::traits::HasStructSize for Builder<'a> {
+ const STRUCT_SIZE: ::capnp::private::layout::StructSize =
+ ::capnp::private::layout::StructSize {
+ data: 1,
+ pointers: 1,
+ };
+ }
+ impl<'a> ::capnp::traits::HasTypeId for Builder<'a> {
+ const TYPE_ID: u64 = _private::TYPE_ID;
+ }
+ impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> {
+ fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self {
+ Self { 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) -> Self {
+ builder
+ .init_struct(::STRUCT_SIZE)
+ .into()
+ }
+ fn get_from_pointer(
+ builder: ::capnp::private::layout::PointerBuilder<'a>,
+ default: ::core::option::Option<&'a [capnp::Word]>,
+ ) -> ::capnp::Result {
+ ::core::result::Result::Ok(
+ builder
+ .get_struct(
+ ::STRUCT_SIZE,
+ default,
+ )?
+ .into(),
+ )
+ }
+ }
+
+ impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> {
+ fn set_pointer_builder(
+ mut pointer: ::capnp::private::layout::PointerBuilder<'_>,
+ value: Self,
+ canonicalize: bool,
+ ) -> ::capnp::Result<()> {
+ pointer.set_struct(&value.reader, canonicalize)
+ }
+ }
+
+ impl<'a> Builder<'a> {
+ pub fn into_reader(self) -> Reader<'a> {
+ self.builder.into_reader().into()
+ }
+ pub fn reborrow(&mut self) -> Builder<'_> {
+ Builder {
+ builder: self.builder.reborrow(),
+ }
+ }
+ pub fn reborrow_as_reader(&self) -> Reader<'_> {
+ self.builder.as_reader().into()
+ }
+
+ pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
+ self.builder.as_reader().total_size()
+ }
+ #[inline]
+ pub fn get_name(self) -> ::capnp::Result<::capnp::text::Builder<'a>> {
+ ::capnp::traits::FromPointerBuilder::get_from_pointer(
+ self.builder.get_pointer_field(0),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn set_name(&mut self, value: ::capnp::text::Reader<'_>) {
+ self.builder.reborrow().get_pointer_field(0).set_text(value);
+ }
+ #[inline]
+ pub fn init_name(self, size: u32) -> ::capnp::text::Builder<'a> {
+ self.builder.get_pointer_field(0).init_text(size)
+ }
+ #[inline]
+ pub fn has_name(&self) -> bool {
+ !self.builder.is_pointer_field_null(0)
+ }
+ #[inline]
+ pub fn get_age(self) -> u8 {
+ self.builder.get_data_field::(0)
+ }
+ #[inline]
+ pub fn set_age(&mut self, value: u8) {
+ self.builder.set_data_field::(0, value);
+ }
+ }
+
+ pub struct Pipeline {
+ _typeless: ::capnp::any_pointer::Pipeline,
+ }
+ impl ::capnp::capability::FromTypelessPipeline for Pipeline {
+ fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self {
+ Self {
+ _typeless: typeless,
+ }
+ }
+ }
+ impl Pipeline {}
+ mod _private {
+ pub const TYPE_ID: u64 = 0xaa1d_7a63_00c7_5ded;
+ }
+}
+
+pub mod message {
+ #[derive(Copy, Clone)]
+ pub struct Owned(());
+ impl ::capnp::traits::Owned for Owned {
+ type Reader<'a> = Reader<'a>;
+ type Builder<'a> = Builder<'a>;
+ }
+ impl ::capnp::traits::OwnedStruct for Owned {
+ type Reader<'a> = Reader<'a>;
+ type Builder<'a> = 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> {
+ const TYPE_ID: u64 = _private::TYPE_ID;
+ }
+ impl<'a> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a> {
+ fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self {
+ Self { reader }
+ }
+ }
+
+ impl<'a> ::capnp::traits::FromPointerReader<'a> for Reader<'a> {
+ fn get_from_pointer(
+ reader: &::capnp::private::layout::PointerReader<'a>,
+ default: ::core::option::Option<&'a [capnp::Word]>,
+ ) -> ::capnp::Result {
+ ::core::result::Result::Ok(reader.get_struct(default)?.into())
+ }
+ }
+
+ 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<'_> {
+ Self { ..*self }
+ }
+
+ pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
+ self.reader.total_size()
+ }
+ #[inline]
+ pub fn get_sender(self) -> ::capnp::Result> {
+ ::capnp::traits::FromPointerReader::get_from_pointer(
+ &self.reader.get_pointer_field(0),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn has_sender(&self) -> bool {
+ !self.reader.get_pointer_field(0).is_null()
+ }
+ #[inline]
+ pub fn get_reciever(
+ self,
+ ) -> ::capnp::Result<::capnp::struct_list::Reader<'a, crate::protocol_capnp::user::Owned>>
+ {
+ ::capnp::traits::FromPointerReader::get_from_pointer(
+ &self.reader.get_pointer_field(1),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn has_reciever(&self) -> bool {
+ !self.reader.get_pointer_field(1).is_null()
+ }
+ #[inline]
+ pub fn get_content(self) -> ::capnp::Result<::capnp::text::Reader<'a>> {
+ ::capnp::traits::FromPointerReader::get_from_pointer(
+ &self.reader.get_pointer_field(2),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn has_content(&self) -> bool {
+ !self.reader.get_pointer_field(2).is_null()
+ }
+ #[inline]
+ pub fn get_time(self) -> i64 {
+ self.reader.get_data_field::(0)
+ }
+ }
+
+ pub struct Builder<'a> {
+ builder: ::capnp::private::layout::StructBuilder<'a>,
+ }
+ impl<'a> ::capnp::traits::HasStructSize for Builder<'a> {
+ const STRUCT_SIZE: ::capnp::private::layout::StructSize =
+ ::capnp::private::layout::StructSize {
+ data: 1,
+ pointers: 3,
+ };
+ }
+ impl<'a> ::capnp::traits::HasTypeId for Builder<'a> {
+ const TYPE_ID: u64 = _private::TYPE_ID;
+ }
+ impl<'a> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a> {
+ fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self {
+ Self { 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) -> Self {
+ builder
+ .init_struct(::STRUCT_SIZE)
+ .into()
+ }
+ fn get_from_pointer(
+ builder: ::capnp::private::layout::PointerBuilder<'a>,
+ default: ::core::option::Option<&'a [capnp::Word]>,
+ ) -> ::capnp::Result {
+ ::core::result::Result::Ok(
+ builder
+ .get_struct(
+ ::STRUCT_SIZE,
+ default,
+ )?
+ .into(),
+ )
+ }
+ }
+
+ impl<'a> ::capnp::traits::SetPointerBuilder for Reader<'a> {
+ fn set_pointer_builder(
+ mut pointer: ::capnp::private::layout::PointerBuilder<'_>,
+ value: Self,
+ canonicalize: bool,
+ ) -> ::capnp::Result<()> {
+ pointer.set_struct(&value.reader, canonicalize)
+ }
+ }
+
+ impl<'a> Builder<'a> {
+ pub fn into_reader(self) -> Reader<'a> {
+ self.builder.into_reader().into()
+ }
+ pub fn reborrow(&mut self) -> Builder<'_> {
+ Builder {
+ builder: self.builder.reborrow(),
+ }
+ }
+ pub fn reborrow_as_reader(&self) -> Reader<'_> {
+ self.builder.as_reader().into()
+ }
+
+ pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
+ self.builder.as_reader().total_size()
+ }
+ #[inline]
+ pub fn get_sender(self) -> ::capnp::Result> {
+ ::capnp::traits::FromPointerBuilder::get_from_pointer(
+ self.builder.get_pointer_field(0),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn set_sender(
+ &mut self,
+ value: crate::protocol_capnp::user::Reader<'_>,
+ ) -> ::capnp::Result<()> {
+ ::capnp::traits::SetPointerBuilder::set_pointer_builder(
+ self.builder.reborrow().get_pointer_field(0),
+ value,
+ false,
+ )
+ }
+ #[inline]
+ pub fn init_sender(self) -> crate::protocol_capnp::user::Builder<'a> {
+ ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), 0)
+ }
+ #[inline]
+ pub fn has_sender(&self) -> bool {
+ !self.builder.is_pointer_field_null(0)
+ }
+ #[inline]
+ pub fn get_reciever(
+ self,
+ ) -> ::capnp::Result<::capnp::struct_list::Builder<'a, crate::protocol_capnp::user::Owned>>
+ {
+ ::capnp::traits::FromPointerBuilder::get_from_pointer(
+ self.builder.get_pointer_field(1),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn set_reciever(
+ &mut self,
+ value: ::capnp::struct_list::Reader<'a, crate::protocol_capnp::user::Owned>,
+ ) -> ::capnp::Result<()> {
+ ::capnp::traits::SetPointerBuilder::set_pointer_builder(
+ self.builder.reborrow().get_pointer_field(1),
+ value,
+ false,
+ )
+ }
+ #[inline]
+ pub fn init_reciever(
+ self,
+ size: u32,
+ ) -> ::capnp::struct_list::Builder<'a, crate::protocol_capnp::user::Owned> {
+ ::capnp::traits::FromPointerBuilder::init_pointer(
+ self.builder.get_pointer_field(1),
+ size,
+ )
+ }
+ #[inline]
+ pub fn has_reciever(&self) -> bool {
+ !self.builder.is_pointer_field_null(1)
+ }
+ #[inline]
+ pub fn get_content(self) -> ::capnp::Result<::capnp::text::Builder<'a>> {
+ ::capnp::traits::FromPointerBuilder::get_from_pointer(
+ self.builder.get_pointer_field(2),
+ ::core::option::Option::None,
+ )
+ }
+ #[inline]
+ pub fn set_content(&mut self, value: ::capnp::text::Reader<'_>) {
+ self.builder.reborrow().get_pointer_field(2).set_text(value);
+ }
+ #[inline]
+ pub fn init_content(self, size: u32) -> ::capnp::text::Builder<'a> {
+ self.builder.get_pointer_field(2).init_text(size)
+ }
+ #[inline]
+ pub fn has_content(&self) -> bool {
+ !self.builder.is_pointer_field_null(2)
+ }
+ #[inline]
+ pub fn get_time(self) -> i64 {
+ self.builder.get_data_field::(0)
+ }
+ #[inline]
+ pub fn set_time(&mut self, value: i64) {
+ self.builder.set_data_field::(0, value);
+ }
+ }
+
+ pub struct Pipeline {
+ _typeless: ::capnp::any_pointer::Pipeline,
+ }
+ impl ::capnp::capability::FromTypelessPipeline for Pipeline {
+ fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self {
+ Self {
+ _typeless: typeless,
+ }
+ }
+ }
+ impl Pipeline {
+ pub fn get_sender(&self) -> crate::protocol_capnp::user::Pipeline {
+ ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0))
+ }
+ }
+ mod _private {
+ pub const TYPE_ID: u64 = 0xa8c3_12bc_6f70_3fa1;
+ }
+}