From 76f11a4c10a2dc448d433971a76430ffc5c9f714 Mon Sep 17 00:00:00 2001 From: lurchi Date: Mon, 5 Sep 2016 15:35:57 +0200 Subject: [PATCH 1/9] remove the unneeded parser structs --- rust/src/parser_types.rs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/rust/src/parser_types.rs b/rust/src/parser_types.rs index 32814d5..aa4dc12 100644 --- a/rust/src/parser_types.rs +++ b/rust/src/parser_types.rs @@ -35,39 +35,6 @@ pub struct PsycParseListState { elemlen_found: u8 } -#[repr(C)] -pub struct PsycParseDictState { - pub buffer: PsycString, - pub cursor: usize, - startc: usize, - elemlen: usize, - elem_parsed: usize, - part: PsycDictPart, - elemlen_found: u8 -} - -#[repr(C)] -pub struct PsycParseIndexState { - buffer: PsycString, - pub cursor: usize, - startc: usize, - elemlen: usize, - elem_parsed: usize, - part: PsycIndexPart, - elemlen_found: u8 -} - -#[repr(C)] -pub struct PsycParseUpdateState { - buffer: PsycString, - pub cursor: usize, - startc: usize, - elemlen: usize, - elem_parsed: usize, - part: PsycUpdatePart, - elemlen_found: u8 -} - #[repr(C)] pub enum PsycParseFlag { /// Default Flag. Parse everything. From 700e5fff8b40ca228a5d45a8f0116ec68636ab80 Mon Sep 17 00:00:00 2001 From: lurchi Date: Wed, 7 Sep 2016 15:14:35 +0200 Subject: [PATCH 2/9] slice::from_raw_parts must not be called on null pointer --- rust/src/packet_types.rs | 20 ++++++++++---------- rust/src/parser.rs | 9 ++++++--- rust/src/util.rs | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/rust/src/packet_types.rs b/rust/src/packet_types.rs index a316609..3ab9d11 100644 --- a/rust/src/packet_types.rs +++ b/rust/src/packet_types.rs @@ -33,6 +33,16 @@ pub enum PsycPacketFlag { PSYC_PACKET_NO_LENGTH = 2, } +#[repr(C)] +pub enum PsycPacketId { + PSYC_PACKET_ID_CONTEXT = 0, + PSYC_PACKET_ID_SOURCE = 1, + PSYC_PACKET_ID_TARGET = 2, + PSYC_PACKET_ID_COUNTER = 3, + PSYC_PACKET_ID_FRAGMENT = 4, + PSYC_PACKET_ID_ELEMS = 5, +} + #[derive(Copy, Clone)] #[repr(C)] pub enum PsycOperator { @@ -51,16 +61,6 @@ pub enum PsycStateOp { PSYC_STATE_RESYNC = '?' as _, } -#[repr(C)] -pub enum PsycPacketId { - PSYC_PACKET_ID_CONTEXT = 0, - PSYC_PACKET_ID_SOURCE = 1, - PSYC_PACKET_ID_TARGET = 2, - PSYC_PACKET_ID_COUNTER = 3, - PSYC_PACKET_ID_FRAGMENT = 4, - PSYC_PACKET_ID_ELEMS = 5, -} - #[repr(C)] pub struct PsycElem { pub elem_type: PsycString, diff --git a/rust/src/parser.rs b/rust/src/parser.rs index ffe3963..eba4a5c 100644 --- a/rust/src/parser.rs +++ b/rust/src/parser.rs @@ -300,21 +300,24 @@ impl PsycListParser { PsycParseListRC::PSYC_PARSE_LIST_ELEM_START => { let result = PsycListParserResult::ListElementStart { - value_part: util::cstring_to_slice(element.data, element.length) + value_part: util::cstring_to_slice(element.data, + element.length) }; return Ok(result) }, PsycParseListRC::PSYC_PARSE_LIST_ELEM_CONT => { let result = PsycListParserResult::ListElementCont { - value_part: util::cstring_to_slice(element.data, element.length) + value_part: util::cstring_to_slice(element.data, + element.length) }; return Ok(result) }, PsycParseListRC::PSYC_PARSE_LIST_ELEM_END => { let result = PsycListParserResult::ListElementEnd { - value_part: util::cstring_to_slice(element.data, element.length) + value_part: util::cstring_to_slice(element.data, + element.length) }; return Ok(result) }, diff --git a/rust/src/util.rs b/rust/src/util.rs index e40f84c..3cd4fcb 100644 --- a/rust/src/util.rs +++ b/rust/src/util.rs @@ -1,13 +1,23 @@ use packet_types::{RawPsycList, PsycRenderRC}; use std::slice; use std::os::raw::c_char; +use std::str; extern "C" { fn psyc_render_list(list: *const RawPsycList, buffer: *mut c_char, buflen: usize) -> PsycRenderRC; } -pub unsafe fn cstring_to_slice<'a>(cstring: *const c_char, length: usize) -> &'a[u8] { - slice::from_raw_parts(cstring as *const u8, length) +pub unsafe fn cstring_to_slice<'a>(cstring: *const c_char, length: usize) + -> &'a[u8] { + match cstring { + p if p.is_null() => &[], + _ => slice::from_raw_parts(cstring as *const u8, length) + } +} + +pub unsafe fn cstring_to_str<'a>(cstring: *const c_char, length: usize) + -> &'a str { + str::from_utf8_unchecked(cstring_to_slice(cstring, length)) } pub unsafe fn render_list(list: &RawPsycList) -> Vec { From 006ed09bb1b7ed65a6edd973b2b038bcb93f0b67 Mon Sep 17 00:00:00 2001 From: lurchi Date: Wed, 7 Sep 2016 19:25:44 +0200 Subject: [PATCH 3/9] add uniform parsing --- rust/src/lib.rs | 8 +- rust/src/types.rs | 1 + rust/src/uniform.rs | 158 +++++++++++++++++++++++++++++++++++ rust/src/uniform_types.rs | 64 ++++++++++++++ rust/tests/test_packet.rs | 1 - rust/tests/test_packet_id.rs | 1 - 6 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 rust/src/uniform.rs create mode 100644 rust/src/uniform_types.rs diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 3bc2edc..cdb2b18 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,12 +1,16 @@ #![allow(dead_code)] mod types; mod util; -pub mod parser_types; -pub mod packet_types; +mod uniform_types; +mod packet_types; +mod parser_types; pub mod parser; pub mod packet; pub mod packet_id; +pub mod uniform; pub use parser::*; pub use packet::*; pub use packet_id::*; +pub use uniform::*; +pub use packet_types::{PsycOperator, PsycStateOp}; diff --git a/rust/src/types.rs b/rust/src/types.rs index 09ef3e0..55431ca 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -1,5 +1,6 @@ use std::os::raw::c_char; +#[derive(Clone)] #[repr(C)] pub struct PsycString { pub length: usize, diff --git a/rust/src/uniform.rs b/rust/src/uniform.rs new file mode 100644 index 0000000..4f5603a --- /dev/null +++ b/rust/src/uniform.rs @@ -0,0 +1,158 @@ +use uniform_types::*; +use std::os::raw::c_char; +use std::os::raw::c_int; +use std::marker::PhantomData; +use std::mem; +use util; + +extern "C" { + fn psyc_uniform_parse(uniform: *mut PsycUniform, + buffer: *const c_char, + length: usize) + -> c_int; +} + +pub struct Uniform<'a> { + uniform: PsycUniform, + phantom: PhantomData<&'a Vec> +} + +impl<'a> Uniform<'a> { + pub fn from_bytes(buffer: &'a [u8]) -> Result { + let buffer_ptr = buffer.as_ptr() as *const c_char; + let mut uniform: PsycUniform; + unsafe { + uniform = mem::zeroed(); + let uniform_ptr = &mut uniform as *mut PsycUniform; + let parse_result = psyc_uniform_parse(uniform_ptr, buffer_ptr, buffer.len()); + if parse_result < PsycScheme::PSYC_SCHEME_PSYC as _ { + return Err(mem::transmute(parse_result)) + } + } + let result = Uniform { + uniform: uniform, + phantom: PhantomData + }; + Ok(result) + } + + //pub fn from_raw_uniform(uniform: PsycUniform) -> Self { + // UniformRef { + // uniform: uniform, + // phantom: PhantomData + // } + //} + + pub fn is_valid(&self) -> bool { + self.uniform.valid + } + + pub fn scheme(&self) -> PsycScheme { + self.uniform.uniform_type + } + + pub fn name(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.user.data, self.uniform.user.length) + } + } + + pub fn password(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.pass.data, self.uniform.pass.length) + } + } + + pub fn host(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.host.data, self.uniform.host.length) + } + } + + pub fn port(&self) -> Option { + let slice: &'a str; + unsafe { + slice = util::cstring_to_str(self.uniform.port.data, + self.uniform.port.length) + } + match slice { + "" => None, + s => Some(s.parse::().unwrap()) + } + } + + pub fn transport(&self) -> Option { + let slice: &'a str; + unsafe { + slice = util::cstring_to_str(self.uniform.transport.data, + self.uniform.transport.length) + } + match slice { + "" => None, + tcp if tcp.as_bytes()[0] == PsycTransport::PSYC_TRANSPORT_TCP as u8 => + Some(PsycTransport::PSYC_TRANSPORT_TCP), + udp if udp.as_bytes()[0] == PsycTransport::PSYC_TRANSPORT_UDP as u8 => + Some(PsycTransport::PSYC_TRANSPORT_UDP), + tls if tls.as_bytes()[0] == PsycTransport::PSYC_TRANSPORT_TLS as u8 => + Some(PsycTransport::PSYC_TRANSPORT_TLS), + gnunet if gnunet.as_bytes()[0] == PsycTransport::PSYC_TRANSPORT_GNUNET as u8 => + Some(PsycTransport::PSYC_TRANSPORT_GNUNET), + _ => None + } + } + + pub fn resource(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.resource.data, + self.uniform.resource.length) + } + } + + pub fn query(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.query.data, self.uniform.query.length) + } + } + + pub fn channel(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.channel.data, self.uniform.channel.length) + } + } + + pub fn full(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.full.data, self.uniform.full.length) + } + } + + pub fn body(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.body.data, self.uniform.body.length) + } + } + + pub fn root(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.root.data, self.uniform.root.length) + } + } + + pub fn entity(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.entity.data, self.uniform.entity.length) + } + } + + pub fn path(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.path.data, self.uniform.path.length) + } + } + + pub fn nick(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.nick.data, self.uniform.nick.length) + } + } +} diff --git a/rust/src/uniform_types.rs b/rust/src/uniform_types.rs new file mode 100644 index 0000000..b68e931 --- /dev/null +++ b/rust/src/uniform_types.rs @@ -0,0 +1,64 @@ +use types::*; + +#[derive(Clone, Copy)] +#[repr(C)] +pub enum PsycScheme { + PSYC_SCHEME_PSYC = 0, + PSYC_SCHEME_IRC = 1, + PSYC_SCHEME_XMPP = 2, + PSYC_SCHEME_SIP = 3 +} + +#[repr(C)] +pub enum PsycEntityType { + PSYC_ENTITY_ROOT = 0, + PSYC_ENTITY_PERSON = '~' as _, + PSYC_ENTITY_PLACE = '@' as _, + PSYC_ENTITY_SERVICE = '$' as _ +} + +#[repr(C)] +pub enum PsycTransport { + PSYC_TRANSPORT_TCP = 'c' as _, + PSYC_TRANSPORT_UDP = 'd' as _, + PSYC_TRANSPORT_TLS = 's' as _, + PSYC_TRANSPORT_GNUNET = 'g' as _, +} + +#[repr(C)] +pub enum UniformParseError { + PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, + PSYC_PARSE_UNIFORM_INVALID_CHANNEL = -6, + PSYC_PARSE_UNIFORM_INVALID_RESOURCE = -5, + PSYC_PARSE_UNIFORM_INVALID_TRANSPORT = -4, + PSYC_PARSE_UNIFORM_INVALID_PORT = -3, + PSYC_PARSE_UNIFORM_INVALID_HOST = -2, + PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, +} + +#[derive(Clone)] +#[repr(C)] +pub struct PsycUniform { + pub valid: bool, + pub uniform_type: PsycScheme, + pub scheme: PsycString, + pub user: PsycString, + pub pass: PsycString, + pub host: PsycString, + pub port: PsycString, + pub transport: PsycString, + pub resource: PsycString, + pub query: PsycString, + pub channel: PsycString, + + pub full: PsycString, + pub body: PsycString, + pub user_host: PsycString, + pub host_port: PsycString, + pub root: PsycString, + pub entity: PsycString, + pub slashes: PsycString, + pub slash: PsycString, + pub path: PsycString, + pub nick: PsycString +} diff --git a/rust/tests/test_packet.rs b/rust/tests/test_packet.rs index aa51797..c24dfc1 100644 --- a/rust/tests/test_packet.rs +++ b/rust/tests/test_packet.rs @@ -1,7 +1,6 @@ extern crate psyc; use psyc::*; -use psyc::packet_types::*; #[test] fn test_create_render() { diff --git a/rust/tests/test_packet_id.rs b/rust/tests/test_packet_id.rs index 58e822c..125ff44 100644 --- a/rust/tests/test_packet_id.rs +++ b/rust/tests/test_packet_id.rs @@ -1,7 +1,6 @@ extern crate psyc; use psyc::*; -use psyc::packet_types::*; #[test] fn test_packet_id() { From 29103a611aca26d9abac6b8abc55dc98f738c5ed Mon Sep 17 00:00:00 2001 From: lurchi Date: Sat, 10 Sep 2016 10:50:35 +0200 Subject: [PATCH 4/9] fix off-by-one error in nick parsing --- src/uniform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uniform.c b/src/uniform.c index 75c617c..f58c20a 100644 --- a/src/uniform.c +++ b/src/uniform.c @@ -184,7 +184,7 @@ psyc_uniform_parse (PsycUniform *uni, const char *buffer, size_t length) } if (uni->resource.length) - uni->nick = PSYC_STRING(uni->resource.data + 1, uni->resource.length); + uni->nick = PSYC_STRING(uni->resource.data + 1, uni->resource.length - 1); } else return PSYC_PARSE_UNIFORM_INVALID_SCHEME; From 393d3d08835c172777f96a736fcbbdb37db246e6 Mon Sep 17 00:00:00 2001 From: lurchi Date: Sat, 10 Sep 2016 13:11:50 +0200 Subject: [PATCH 5/9] change uniform interface for more comprehensive access to entity data --- rust/src/lib.rs | 1 + rust/src/types.rs | 9 +++++- rust/src/uniform.rs | 68 ++++++++++++++++++++++++++++----------- rust/src/uniform_types.rs | 26 ++++++++++++++- 4 files changed, 83 insertions(+), 21 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index cdb2b18..1850e8e 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -13,4 +13,5 @@ pub use parser::*; pub use packet::*; pub use packet_id::*; pub use uniform::*; +pub use uniform_types::{UniformParseError, PsycScheme, PsycEntity}; pub use packet_types::{PsycOperator, PsycStateOp}; diff --git a/rust/src/types.rs b/rust/src/types.rs index 55431ca..4011d8c 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -1,6 +1,13 @@ use std::os::raw::c_char; -#[derive(Clone)] +/// Return code: OK/error. +#[repr(C)] +pub enum PsycRC { + PSYC_OK = 1, + PSYC_ERROR = -1, +} + +#[derive(Debug)] #[repr(C)] pub struct PsycString { pub length: usize, diff --git a/rust/src/uniform.rs b/rust/src/uniform.rs index 4f5603a..9c8c823 100644 --- a/rust/src/uniform.rs +++ b/rust/src/uniform.rs @@ -1,3 +1,4 @@ +use types::PsycRC; use uniform_types::*; use std::os::raw::c_char; use std::os::raw::c_int; @@ -10,8 +11,11 @@ extern "C" { buffer: *const c_char, length: usize) -> c_int; + + fn psyc_entity_type(entity: c_char) -> c_int; } +#[derive(Debug)] pub struct Uniform<'a> { uniform: PsycUniform, phantom: PhantomData<&'a Vec> @@ -47,14 +51,45 @@ impl<'a> Uniform<'a> { self.uniform.valid } - pub fn scheme(&self) -> PsycScheme { - self.uniform.uniform_type + pub fn entity(&self) -> PsycEntity<'a> { + match self.resource() { + "" => PsycEntity::Root, + _resource => unsafe { + let type_specifier = *self.uniform.resource.data; + let entity_type_int = psyc_entity_type(type_specifier); + if entity_type_int == PsycRC::PSYC_ERROR as c_int { + return PsycEntity::Unknown { + object: self.resource(), + channel: self.channel() + } + } + + let entity_type: PsycEntityType = mem::transmute(entity_type_int); + + match entity_type { + PsycEntityType::PSYC_ENTITY_PERSON => PsycEntity::Person { + name: self.nick(), + channel: self.channel() + }, + + PsycEntityType::PSYC_ENTITY_PLACE => PsycEntity::Place { + name: self.nick(), + channel: self.channel() + }, + + PsycEntityType::PSYC_ENTITY_SERVICE => PsycEntity::Service { + name: self.nick(), + channel: self.channel() + }, + + PsycEntityType::PSYC_ENTITY_ROOT => PsycEntity::Root + } + } + } } - pub fn name(&self) -> &'a str { - unsafe { - util::cstring_to_str(self.uniform.user.data, self.uniform.user.length) - } + pub fn scheme(&self) -> PsycScheme { + self.uniform.uniform_type } pub fn password(&self) -> &'a str { @@ -114,12 +149,6 @@ impl<'a> Uniform<'a> { } } - pub fn channel(&self) -> &'a str { - unsafe { - util::cstring_to_str(self.uniform.channel.data, self.uniform.channel.length) - } - } - pub fn full(&self) -> &'a str { unsafe { util::cstring_to_str(self.uniform.full.data, self.uniform.full.length) @@ -138,21 +167,22 @@ impl<'a> Uniform<'a> { } } - pub fn entity(&self) -> &'a str { - unsafe { - util::cstring_to_str(self.uniform.entity.data, self.uniform.entity.length) - } - } - pub fn path(&self) -> &'a str { unsafe { util::cstring_to_str(self.uniform.path.data, self.uniform.path.length) } } - pub fn nick(&self) -> &'a str { + /* private functions */ + fn nick(&self) -> &'a str { unsafe { util::cstring_to_str(self.uniform.nick.data, self.uniform.nick.length) } } + + fn channel(&self) -> &'a str { + unsafe { + util::cstring_to_str(self.uniform.channel.data, self.uniform.channel.length) + } + } } diff --git a/rust/src/uniform_types.rs b/rust/src/uniform_types.rs index b68e931..069a46a 100644 --- a/rust/src/uniform_types.rs +++ b/rust/src/uniform_types.rs @@ -1,6 +1,28 @@ use types::*; +#[derive(Debug, PartialEq)] +pub enum PsycEntity<'a> { + Root, + Person { + name: &'a str, + channel: &'a str + }, + Place { + name: &'a str, + channel: &'a str + }, + Service { + name: &'a str, + channel: &'a str + }, + Unknown { + object: &'a str, + channel: &'a str + } +} + #[derive(Clone, Copy)] +#[derive(Debug, PartialEq)] #[repr(C)] pub enum PsycScheme { PSYC_SCHEME_PSYC = 0, @@ -17,6 +39,7 @@ pub enum PsycEntityType { PSYC_ENTITY_SERVICE = '$' as _ } +#[derive(Debug, PartialEq)] #[repr(C)] pub enum PsycTransport { PSYC_TRANSPORT_TCP = 'c' as _, @@ -25,6 +48,7 @@ pub enum PsycTransport { PSYC_TRANSPORT_GNUNET = 'g' as _, } +#[derive(Debug, PartialEq)] #[repr(C)] pub enum UniformParseError { PSYC_PARSE_UNIFORM_INVALID_SLASHES = -7, @@ -36,7 +60,7 @@ pub enum UniformParseError { PSYC_PARSE_UNIFORM_INVALID_SCHEME = -1, } -#[derive(Clone)] +#[derive(Debug)] #[repr(C)] pub struct PsycUniform { pub valid: bool, From f146435e992009fb49bcd71840bd3b5f8edf2406 Mon Sep 17 00:00:00 2001 From: lurchi Date: Sat, 10 Sep 2016 13:12:06 +0200 Subject: [PATCH 6/9] add uniform tests --- rust/tests/test_uniform.rs | 71 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 rust/tests/test_uniform.rs diff --git a/rust/tests/test_uniform.rs b/rust/tests/test_uniform.rs new file mode 100644 index 0000000..8000ecb --- /dev/null +++ b/rust/tests/test_uniform.rs @@ -0,0 +1,71 @@ +extern crate psyc; + +use psyc::*; + +#[test] +fn test_person() { + let uniform = Uniform::from_bytes(b"psyc://ve.symlynx.com:4404/~lurchi"); + + let unwrapped = uniform.unwrap(); + let entity = unwrapped.entity(); + + assert!(unwrapped.is_valid()); + assert_eq!(unwrapped.full(), "psyc://ve.symlynx.com:4404/~lurchi"); + assert_eq!(unwrapped.scheme(), PsycScheme::PSYC_SCHEME_PSYC); + assert_eq!(unwrapped.host(), "ve.symlynx.com"); + assert_eq!(unwrapped.port(), Some(4404)); + assert_eq!(unwrapped.resource(), "~lurchi"); + + assert_eq!(entity, PsycEntity::Person {name: "lurchi", channel: ""}); +} + +#[test] +fn test_place() { + let uniform = Uniform::from_bytes(b"psyc://ve.symlynx.com/@_strange_place"); + + let unwrapped = uniform.unwrap(); + + assert!(unwrapped.is_valid()); + assert_eq!(unwrapped.resource(), "@_strange_place"); + assert_eq!(unwrapped.entity(), + PsycEntity::Place {name: "_strange_place", channel: ""}); + +} + +#[test] +fn test_host_only() { + let uniform = Uniform::from_bytes(b"psyc://ve.symlynx.com"); + + let unwrapped = uniform.unwrap(); + + assert!(unwrapped.is_valid()); + assert_eq!(unwrapped.resource(), ""); + assert_eq!(unwrapped.entity(), PsycEntity::Root); +} + +#[test] +fn test_unknown_resource() { + let uniform = Uniform::from_bytes(b"psyc://ve.symlynx.com/%unknown#a"); + + let unwrapped = uniform.unwrap(); + + assert!(unwrapped.is_valid()); + assert_eq!(unwrapped.entity(), + PsycEntity::Unknown {object: "%unknown", channel: "a"}); +} + +#[test] +fn test_channel() { + let uniform = Uniform::from_bytes(b"psyc://ve.symlynx.com:4404/~lurchi#test"); + + let unwrapped = uniform.unwrap(); + + assert_eq!(unwrapped.entity(), PsycEntity::Person {name: "lurchi", channel: "test"}); +} + +#[test] +fn test_empty() { + let uniform = Uniform::from_bytes(b""); + assert_eq!(uniform.unwrap_err(), + UniformParseError::PSYC_PARSE_UNIFORM_INVALID_SCHEME); +} From 27dc1292bae2e078e153a8079b65bc1fddb30315 Mon Sep 17 00:00:00 2001 From: lurchi Date: Sat, 10 Sep 2016 19:55:52 +0200 Subject: [PATCH 7/9] body members are now called method and data (according to spec) --- rust/src/parser.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rust/src/parser.rs b/rust/src/parser.rs index eba4a5c..5bd2e23 100644 --- a/rust/src/parser.rs +++ b/rust/src/parser.rs @@ -59,18 +59,18 @@ pub enum PsycParserResult<'a> { value_part: &'a [u8] }, Body { - name: &'a [u8], - value: &'a [u8] + method: &'a [u8], + data: &'a [u8] }, BodyStart { - name: &'a [u8], - value_part: &'a [u8] + method: &'a [u8], + data_part: &'a [u8] }, BodyCont { - value_part: &'a [u8] + data_part: &'a [u8] }, BodyEnd { - value_part: &'a [u8] + data_part: &'a [u8] } } @@ -207,29 +207,29 @@ impl PsycParser { PsycParseRC::PSYC_PARSE_BODY => { let result = PsycParserResult::Body { - name: util::cstring_to_slice(name.data, name.length), - value: util::cstring_to_slice(value.data, value.length) + method: util::cstring_to_slice(name.data, name.length), + data: util::cstring_to_slice(value.data, value.length) }; Ok(result) }, PsycParseRC::PSYC_PARSE_BODY_START => { let result = PsycParserResult::BodyStart { - name: util::cstring_to_slice(name.data, name.length), - value_part: util::cstring_to_slice(value.data, value.length) + method: util::cstring_to_slice(name.data, name.length), + data_part: util::cstring_to_slice(value.data, value.length) }; Ok(result) }, PsycParseRC::PSYC_PARSE_BODY_CONT => { let result = PsycParserResult::BodyCont { - value_part: util::cstring_to_slice(value.data, value.length) + data_part: util::cstring_to_slice(value.data, value.length) }; Ok(result) }, PsycParseRC::PSYC_PARSE_BODY_END => { let result = PsycParserResult::BodyEnd { - value_part: util::cstring_to_slice(value.data, value.length) + data_part: util::cstring_to_slice(value.data, value.length) }; Ok(result) } From 749d0abf7973ac0d6612d7357e8aa1b00f13cf3d Mon Sep 17 00:00:00 2001 From: lurchi Date: Sun, 11 Sep 2016 03:11:14 +0200 Subject: [PATCH 8/9] add variable and method modules --- rust/Cargo.toml | 3 ++ rust/src/keyword.rs | 36 +++++++++++++++++++ rust/src/lib.rs | 19 ++++++++-- rust/src/method.rs | 45 ++++++++++++++++++++++++ rust/src/method_types.rs | 61 ++++++++++++++++++++++++++++++++ rust/src/types.rs | 15 +++++++- rust/src/variable.rs | 69 +++++++++++++++++++++++++++++++++++++ rust/src/variable_types.rs | 39 +++++++++++++++++++++ rust/tests/test_method.rs | 38 ++++++++++++++++++++ rust/tests/test_variable.rs | 44 +++++++++++++++++++++++ 10 files changed, 365 insertions(+), 4 deletions(-) create mode 100644 rust/src/keyword.rs create mode 100644 rust/src/method.rs create mode 100644 rust/src/method_types.rs create mode 100644 rust/src/variable.rs create mode 100644 rust/src/variable_types.rs create mode 100644 rust/tests/test_method.rs create mode 100644 rust/tests/test_variable.rs diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 38b5801..5302866 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -4,3 +4,6 @@ version = "1.0.0" links = "psyc" build = "build.rs" description = "rust bindings for libpsyc" + +[dependencies] +bitflags = "0.7.0" diff --git a/rust/src/keyword.rs b/rust/src/keyword.rs new file mode 100644 index 0000000..494dbd2 --- /dev/null +++ b/rust/src/keyword.rs @@ -0,0 +1,36 @@ +use std::os::raw::{c_char, c_int}; + +extern "C" { + fn psyc_inherits(sho: *const c_char, + slen: usize, + lon: *const c_char, + llen: usize) + -> c_int; + fn psyc_matches(sho: *const c_char, + slen: usize, + lon: *const c_char, + llen: usize) + -> c_int; +} + +pub trait Keyword { + fn keyword(&self) -> &[u8]; + + fn inherits(&self, other: &[u8]) -> bool { + let keyword_ptr = self.keyword().as_ptr() as *const c_char; + let other_ptr = other.as_ptr() as *const c_char; + let result = unsafe { + psyc_inherits(other_ptr, other.len(), keyword_ptr, self.keyword().len()) + }; + result == 0 + } + + fn matches(&self, other: &[u8]) -> bool { + let keyword_ptr = self.keyword().as_ptr() as *const c_char; + let other_ptr = other.as_ptr() as *const c_char; + let result = unsafe { + psyc_matches(other_ptr, other.len(), keyword_ptr, self.keyword().len()) + }; + result == 0 + } +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 1850e8e..9630c5f 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -1,17 +1,30 @@ #![allow(dead_code)] -mod types; -mod util; -mod uniform_types; +#[macro_use] +extern crate bitflags; + +mod keyword; +mod method_types; mod packet_types; mod parser_types; +mod types; +mod uniform_types; +mod util; +mod variable_types; +pub mod method; pub mod parser; pub mod packet; pub mod packet_id; pub mod uniform; +pub mod variable; +pub use keyword::Keyword; +pub use method::Method; +pub use method_types::*; pub use parser::*; pub use packet::*; pub use packet_id::*; pub use uniform::*; pub use uniform_types::{UniformParseError, PsycScheme, PsycEntity}; pub use packet_types::{PsycOperator, PsycStateOp}; +pub use variable::*; +pub use variable_types::{PsycRoutingVar, PsycType}; diff --git a/rust/src/method.rs b/rust/src/method.rs new file mode 100644 index 0000000..e1b5cbe --- /dev/null +++ b/rust/src/method.rs @@ -0,0 +1,45 @@ +use method_types::{PsycMethod, PsycMethodFlags, MethodInfo}; +use keyword::Keyword; +use std::mem; +use std::os::raw::{c_char, c_uint}; + +extern "C" { + fn psyc_method(method: *const c_char, + methodlen: usize, + family: *mut PsycMethod, + flag: *mut c_uint) + -> PsycMethod; +} + +pub struct Method<'a> { + pub method: &'a [u8] +} + +impl<'a> Keyword for Method<'a> { + fn keyword(&self) -> &[u8] { + self.method + } +} + +impl<'a> Method<'a> { + pub fn lookup(&self) -> MethodInfo { + let method_ptr = self.method.as_ptr() as *const c_char; + let lookup_result: PsycMethod; + let mut family: PsycMethod; + let mut flags: PsycMethodFlags; + unsafe { + family = mem::uninitialized(); + flags = mem::uninitialized(); + let flags_ptr = &mut flags as *mut PsycMethodFlags as *mut c_uint; + lookup_result = psyc_method(method_ptr, + self.method.len(), + &mut family as *mut PsycMethod, + flags_ptr) + } + MethodInfo { + lookup_result: lookup_result, + family: family, + flags: flags + } + } +} diff --git a/rust/src/method_types.rs b/rust/src/method_types.rs new file mode 100644 index 0000000..b8a44d4 --- /dev/null +++ b/rust/src/method_types.rs @@ -0,0 +1,61 @@ +use std::os::raw::c_int; + +bitflags! { + pub flags PsycMethodFlags: c_int { + const PSYC_METHOD_TEMPLATE = 1 << 0, + const PSYC_METHOD_REPLY = 1 << 1, + const PSYC_METHOD_VISIBLE = 1 << 2, + const PSYC_METHOD_LOGGABLE = 1 << 3, + const PSYC_METHOD_MANUAL = 1 << 4 + } +} + + +#[repr(C)] +#[derive(Debug, PartialEq)] +pub enum PsycMethod { + PSYC_MC_UNKNOWN, + + PSYC_MC_CONVERSE, + PSYC_MC_DATA, + PSYC_MC_ECHO, + PSYC_MC_ECHO_CONTEXT_ENTER, + PSYC_MC_ECHO_CONTEXT_LEAVE, + PSYC_MC_ECHO_HELLO, + PSYC_MC_ERROR, + PSYC_MC_FAILURE, + PSYC_MC_FAILURE_ALIAS_NONEXISTANT, + PSYC_MC_FAILURE_ALIAS_UNAVAILABLE, + PSYC_MC_INFO, + PSYC_MC_MESSAGE, // deprecated, use _converse + PSYC_MC_MESSAGE_ACTION, // deprecated, use _converse + PSYC_MC_NOTICE, + PSYC_MC_NOTICE_ALIAS_ADD, + PSYC_MC_NOTICE_ALIAS_CHANGE, + PSYC_MC_NOTICE_ALIAS_REMOVE, + PSYC_MC_NOTICE_CONTEXT_ENTER, + PSYC_MC_NOTICE_CONTEXT_LEAVE, + PSYC_MC_NOTICE_FRIENDSHIP, + PSYC_MC_NOTICE_LINK, + PSYC_MC_NOTICE_PEER_CONNECT, + PSYC_MC_NOTICE_PEER_DISCONNECT, + PSYC_MC_NOTICE_SET, + PSYC_MC_NOTICE_UNLINK, + PSYC_MC_REQUEST, + PSYC_MC_REQUEST_CONTEXT_ENTER, + PSYC_MC_REQUEST_CONTEXT_LEAVE, + PSYC_MC_REQUEST_FRIENDSHIP, + PSYC_MC_STATUS, + PSYC_MC_STATUS_CONTEXTS_ENTERED, + PSYC_MC_STATUS_HELLO, + PSYC_MC_WARNING, + + PSYC_METHODS_NUM, +} + +#[derive(Debug, PartialEq)] +pub struct MethodInfo { + pub lookup_result: PsycMethod, + pub family: PsycMethod, + pub flags: PsycMethodFlags +} diff --git a/rust/src/types.rs b/rust/src/types.rs index 4011d8c..b23cfa3 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -7,6 +7,12 @@ pub enum PsycRC { PSYC_ERROR = -1, } +#[repr(C)] +pub enum PsycBool { + PSYC_FALSE = 0, + PSYC_TRUE = 1, +} + #[derive(Debug)] #[repr(C)] pub struct PsycString { @@ -14,4 +20,11 @@ pub struct PsycString { pub data: *const c_char } - +impl PsycBool { + pub fn to_bool(self) -> bool { + match self { + PsycBool::PSYC_FALSE => false, + PsycBool::PSYC_TRUE => true + } + } +} diff --git a/rust/src/variable.rs b/rust/src/variable.rs new file mode 100644 index 0000000..155c8a9 --- /dev/null +++ b/rust/src/variable.rs @@ -0,0 +1,69 @@ +use types::PsycBool; +use variable_types::*; +use keyword::Keyword; +use std::os::raw::c_char; + +extern "C" { + fn psyc_var_routing(name: *const c_char, len: usize) -> PsycRoutingVar; + fn psyc_var_type(name: *const c_char, len: usize) -> PsycType; + fn psyc_var_is_list(name: *const c_char, len: usize) -> PsycBool; +} + +pub struct RoutingVariable<'a> { + pub variable: &'a [u8] +} + +pub struct EntityVariable<'a> { + pub variable: &'a [u8] +} + +impl<'a> Variable for RoutingVariable<'a> { + fn variable(&self) -> &[u8] { + self.variable + } +} + +impl<'a> Variable for EntityVariable<'a> { + fn variable(&self) -> &[u8] { + self.variable + } +} + +impl<'a> Keyword for RoutingVariable<'a> { + fn keyword(&self) -> &[u8] { + self.variable + } +} + +impl<'a> Keyword for EntityVariable<'a> { + fn keyword(&self) -> &[u8] { + self.variable + } +} + +impl<'a> RoutingVariable<'a> { + pub fn lookup(&self) -> PsycRoutingVar { + let variable_ptr = self.variable().as_ptr() as *const c_char; + unsafe { + psyc_var_routing(variable_ptr, self.variable().len()) + } + } +} + +pub trait Variable { + fn variable(&self) -> &[u8]; + + fn datatype(&self) -> PsycType { + let variable_ptr = self.variable().as_ptr() as *const c_char; + unsafe { + psyc_var_type(variable_ptr, self.variable().len()) + } + } + + fn is_list(&self) -> bool { + let variable_ptr = self.variable().as_ptr() as *const c_char; + unsafe { + psyc_var_is_list(variable_ptr, self.variable().len()).to_bool() + } + } +} diff --git a/rust/src/variable_types.rs b/rust/src/variable_types.rs new file mode 100644 index 0000000..02baab2 --- /dev/null +++ b/rust/src/variable_types.rs @@ -0,0 +1,39 @@ +#[repr(C)] +#[derive(Debug, PartialEq)] +pub enum PsycRoutingVar { + PSYC_RVAR_UNKNOWN, + + PSYC_RVAR_AMOUNT_FRAGMENTS, + PSYC_RVAR_CONTEXT, + PSYC_RVAR_COUNTER, + PSYC_RVAR_FRAGMENT, + PSYC_RVAR_SOURCE, + PSYC_RVAR_SOURCE_RELAY, + PSYC_RVAR_TAG, + PSYC_RVAR_TAG_RELAY, + PSYC_RVAR_TARGET, + PSYC_RVAR_TARGET_RELAY, + + PSYC_RVARS_NUM, +} + +#[repr(C)] +#[derive(Debug, PartialEq)] +pub enum PsycType { + PSYC_TYPE_UNKNOWN, + PSYC_TYPE_AMOUNT, + PSYC_TYPE_COLOR, + PSYC_TYPE_COUNTER, + PSYC_TYPE_DATE, + PSYC_TYPE_DEGREE, + PSYC_TYPE_DICT, + PSYC_TYPE_ENTITY, + PSYC_TYPE_FLAG, + PSYC_TYPE_LANGUAGE, + PSYC_TYPE_LIST, + PSYC_TYPE_NICK, + PSYC_TYPE_PAGE, + PSYC_TYPE_STRUCT, + PSYC_TYPE_TIME, + PSYC_TYPE_UNIFORM, +} diff --git a/rust/tests/test_method.rs b/rust/tests/test_method.rs new file mode 100644 index 0000000..1372106 --- /dev/null +++ b/rust/tests/test_method.rs @@ -0,0 +1,38 @@ +extern crate psyc; +use psyc::*; + +#[test] +fn test_method_matching() { + let m = Method {method: b"_notice_context_enter"}; + + assert!(m.inherits(b"_notice_context")); + assert!(m.matches(b"_context")); +} + +#[test] +fn test_method_lookup() { + let m = Method {method: b"_notice_context_enter"}; + + let expected_flags = PSYC_METHOD_TEMPLATE | + PSYC_METHOD_VISIBLE | + PSYC_METHOD_LOGGABLE; + + assert_eq!(m.lookup(), + MethodInfo { + lookup_result: PsycMethod::PSYC_MC_NOTICE_CONTEXT_ENTER, + family: PsycMethod::PSYC_MC_NOTICE, + flags: expected_flags + }); +} + +#[test] +fn test_lookup_empty() { + let m = Method {method: b""}; + + assert_eq!(m.lookup(), + MethodInfo { + lookup_result: PsycMethod::PSYC_MC_UNKNOWN, + family: PsycMethod::PSYC_MC_UNKNOWN, + flags: PsycMethodFlags::empty() + }); +} diff --git a/rust/tests/test_variable.rs b/rust/tests/test_variable.rs new file mode 100644 index 0000000..0848af9 --- /dev/null +++ b/rust/tests/test_variable.rs @@ -0,0 +1,44 @@ +extern crate psyc; +use psyc::*; + +#[test] +fn test_routing_variable() { + let r = RoutingVariable {variable: b"_amount_fragments"}; + + assert_eq!(r.lookup(), PsycRoutingVar::PSYC_RVAR_AMOUNT_FRAGMENTS); + assert_eq!(r.datatype(), PsycType::PSYC_TYPE_AMOUNT); + assert_eq!(r.is_list(), false); +} + +#[test] +fn test_entity_variable() { + let e = EntityVariable {variable: b"_nick_family"}; + + assert_eq!(e.datatype(), PsycType::PSYC_TYPE_NICK); + assert!(! e.is_list()); +} + +#[test] +fn test_empty() { + let r = RoutingVariable {variable: b""}; + + assert_eq!(r.lookup(), PsycRoutingVar::PSYC_RVAR_UNKNOWN); + assert_eq!(r.datatype(), PsycType::PSYC_TYPE_UNKNOWN); + assert!(! r.is_list()); +} + +#[test] +fn test_inherits() { + let r = RoutingVariable {variable: b"_target_relay"}; + + assert!(r.inherits(b"_target")); + assert!(! r.inherits(b"")); +} + +#[test] +fn test_matches() { + let r = RoutingVariable {variable: b"_target_relay"}; + + assert!(r.matches(b"_relay")); + assert!(! r.matches(b"")); +} From 3f527b176c7529dda87b7bb135a3a8f841eaf87f Mon Sep 17 00:00:00 2001 From: lurchi Date: Sun, 11 Sep 2016 12:19:35 +0200 Subject: [PATCH 9/9] be explicit about imported and exported types --- rust/src/lib.rs | 15 +++--- rust/src/method_types.rs | 1 - rust/src/packet.rs | 14 ++---- rust/src/packet_id.rs | 3 +- rust/src/packet_types.rs | 8 +++ rust/src/parser.rs | 89 +--------------------------------- rust/src/parser_types.rs | 85 +++++++++++++++++++++++++++++++- rust/src/uniform_types.rs | 2 +- rust/tests/test_list_parser.rs | 2 +- rust/tests/test_parser.rs | 2 +- 10 files changed, 110 insertions(+), 111 deletions(-) diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 9630c5f..f63a058 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -19,12 +19,15 @@ pub mod variable; pub use keyword::Keyword; pub use method::Method; -pub use method_types::*; -pub use parser::*; -pub use packet::*; -pub use packet_id::*; -pub use uniform::*; +pub use method_types::{PsycMethod, MethodInfo, PsycMethodFlags}; +pub use method_types::{PSYC_METHOD_TEMPLATE, PSYC_METHOD_REPLY, PSYC_METHOD_VISIBLE, PSYC_METHOD_LOGGABLE, PSYC_METHOD_MANUAL}; +pub use parser::{PsycParser, PsycListParser, Parser}; +pub use parser_types::{PsycParserResult, PsycListParserResult, PsycParserError, PsycListParserError}; +pub use packet::{PsycList, PsycModifier, PsycPacket}; +pub use packet_id::PacketId; +pub use packet_types::PacketRenderError; +pub use uniform::Uniform; pub use uniform_types::{UniformParseError, PsycScheme, PsycEntity}; pub use packet_types::{PsycOperator, PsycStateOp}; -pub use variable::*; +pub use variable::{RoutingVariable, EntityVariable, Variable}; pub use variable_types::{PsycRoutingVar, PsycType}; diff --git a/rust/src/method_types.rs b/rust/src/method_types.rs index b8a44d4..cfa3a68 100644 --- a/rust/src/method_types.rs +++ b/rust/src/method_types.rs @@ -10,7 +10,6 @@ bitflags! { } } - #[repr(C)] #[derive(Debug, PartialEq)] pub enum PsycMethod { diff --git a/rust/src/packet.rs b/rust/src/packet.rs index e9b9980..ad0ea32 100644 --- a/rust/src/packet.rs +++ b/rust/src/packet.rs @@ -1,6 +1,6 @@ -use types::*; +use types::PsycString; use packet_types::*; -use packet_id::*; +use packet_id::PacketId; use util; use std::mem; use std::ptr; @@ -70,14 +70,6 @@ pub struct PsycPacket<'a> { body: &'a [u8] } -#[repr(C)] -#[derive(Debug, PartialEq)] -pub enum PsycRenderError { - MethodMissing = PsycRenderRC::PSYC_RENDER_ERROR_METHOD_MISSING as _, - ModifierNameMissing = PsycRenderRC::PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING as _, - GenericError = PsycRenderRC::PSYC_RENDER_ERROR as _ -} - impl PsycList { /// Construct a PsycList from a list of byte lists pub fn new(list: &[&[u8]]) -> Self { @@ -212,7 +204,7 @@ impl<'a> PsycPacket<'a> { } /// - pub fn render(&self) -> Result, PsycRenderError> { + pub fn render(&self) -> Result, PacketRenderError> { let raw_packet_ptr = & self.raw_packet as *const RawPsycPacket; let mut buffer = Vec::with_capacity(self.length()); let buffer_ptr = buffer.as_mut_ptr() as *mut c_char; diff --git a/rust/src/packet_id.rs b/rust/src/packet_id.rs index c855dcb..3a75343 100644 --- a/rust/src/packet_id.rs +++ b/rust/src/packet_id.rs @@ -1,5 +1,6 @@ use packet_types::{RawPsycList, PsycElem}; -use parser::{PsycListParser, PsycListParserResult}; +use parser::PsycListParser; +use parser_types::PsycListParserResult; use util; use std::mem; use std::ptr; diff --git a/rust/src/packet_types.rs b/rust/src/packet_types.rs index 3ab9d11..a159310 100644 --- a/rust/src/packet_types.rs +++ b/rust/src/packet_types.rs @@ -116,3 +116,11 @@ pub enum PsycRenderRC { /// Packet is rendered successfully in the buffer. PSYC_RENDER_SUCCESS = 0, } + +#[repr(C)] +#[derive(Debug, PartialEq)] +pub enum PacketRenderError { + MethodMissing = PsycRenderRC::PSYC_RENDER_ERROR_METHOD_MISSING as _, + ModifierNameMissing = PsycRenderRC::PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING as _, + GenericError = PsycRenderRC::PSYC_RENDER_ERROR as _ +} diff --git a/rust/src/parser.rs b/rust/src/parser.rs index 5bd2e23..b676067 100644 --- a/rust/src/parser.rs +++ b/rust/src/parser.rs @@ -1,4 +1,4 @@ -use types::*; +use types::PsycString; use parser_types::*; use util; use std::mem; @@ -31,93 +31,6 @@ pub struct PsycListParser { state: PsycParseListState } -#[derive(Debug, PartialEq)] -pub enum PsycParserResult<'a> { - StateSync, - StateReset, - Complete, - InsufficientData, - RoutingModifier { - operator: char, - name: &'a [u8], - value: &'a [u8] - }, - EntityModifier { - operator: char, - name: &'a [u8], - value: &'a [u8] - }, - EntityModifierStart { - operator: char, - name: &'a [u8], - value_part: &'a [u8] - }, - EntityModifierCont { - value_part: &'a [u8] - }, - EntityModifierEnd { - value_part: &'a [u8] - }, - Body { - method: &'a [u8], - data: &'a [u8] - }, - BodyStart { - method: &'a [u8], - data_part: &'a [u8] - }, - BodyCont { - data_part: &'a [u8] - }, - BodyEnd { - data_part: &'a [u8] - } -} - -#[derive(Debug, PartialEq)] -pub enum PsycListParserResult<'a> { - Complete, - InsufficientData, - ListElement { - value: &'a [u8] - }, - ListElementStart { - value_part: &'a [u8] - }, - ListElementCont { - value_part: &'a [u8] - }, - ListElementEnd { - value_part: &'a [u8] - } -} - -#[repr(C)] -#[derive(Debug, PartialEq)] -pub enum PsycParserError { - NoModifierLength = PsycParseRC::PSYC_PARSE_ERROR_MOD_NO_LEN as _, - NoContentLength = PsycParseRC::PSYC_PARSE_ERROR_NO_LEN as _, - NoEndDelimiter = PsycParseRC::PSYC_PARSE_ERROR_END as _, - NoNewlineAfterMethod = PsycParseRC::PSYC_PARSE_ERROR_METHOD as _, - NoNewlineAfterModifier = PsycParseRC::PSYC_PARSE_ERROR_MOD_NL as _, - InvalidModifierLength = PsycParseRC::PSYC_PARSE_ERROR_MOD_LEN as _, - NoTabBeforeModifierValue = PsycParseRC::PSYC_PARSE_ERROR_MOD_TAB as _, - NoModifierName = PsycParseRC::PSYC_PARSE_ERROR_MOD_NAME as _, - NoNewlineAfterContentLength = PsycParseRC::PSYC_PARSE_ERROR_LENGTH as _, - GenericError = PsycParseRC::PSYC_PARSE_ERROR as _, -} - -#[repr(C)] -#[derive(Debug, PartialEq)] -pub enum PsycListParserError { - NoElementLength = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_NO_LEN as _, - InvalidElementLength = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_LENGTH as _, - InvalidElementType = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_TYPE as _, - InvalidElementStart = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_START as _, - InvalidType = PsycParseListRC::PSYC_PARSE_LIST_ERROR_TYPE as _, - GenericError = PsycParseListRC::PSYC_PARSE_LIST_ERROR as _, -} - impl PsycParser { /// Create a PsycParser pub fn new() -> Self { diff --git a/rust/src/parser_types.rs b/rust/src/parser_types.rs index aa4dc12..b5b5b75 100644 --- a/rust/src/parser_types.rs +++ b/rust/src/parser_types.rs @@ -1,5 +1,5 @@ #![allow(non_camel_case_types)] -use types::*; +use types::PsycString; enum PsycPart { } enum PsycListPart { } @@ -265,6 +265,89 @@ pub enum PsycParseUpdateRC { PSYC_PARSE_UPDATE_END = 27, } +#[derive(Debug, PartialEq)] +pub enum PsycParserResult<'a> { + StateSync, + StateReset, + Complete, + InsufficientData, + RoutingModifier { + operator: char, + name: &'a [u8], + value: &'a [u8] + }, + EntityModifier { + operator: char, + name: &'a [u8], + value: &'a [u8] + }, + EntityModifierStart { + operator: char, + name: &'a [u8], + value_part: &'a [u8] + }, + EntityModifierCont { + value_part: &'a [u8] + }, + EntityModifierEnd { + value_part: &'a [u8] + }, + Body { + method: &'a [u8], + data: &'a [u8] + }, + BodyStart { + method: &'a [u8], + data_part: &'a [u8] + }, + BodyCont { + data_part: &'a [u8] + }, + BodyEnd { + data_part: &'a [u8] + } +} +#[derive(Debug, PartialEq)] +pub enum PsycListParserResult<'a> { + Complete, + InsufficientData, + ListElement { + value: &'a [u8] + }, + ListElementStart { + value_part: &'a [u8] + }, + ListElementCont { + value_part: &'a [u8] + }, + ListElementEnd { + value_part: &'a [u8] + } +} +#[repr(C)] +#[derive(Debug, PartialEq)] +pub enum PsycParserError { + NoModifierLength = PsycParseRC::PSYC_PARSE_ERROR_MOD_NO_LEN as _, + NoContentLength = PsycParseRC::PSYC_PARSE_ERROR_NO_LEN as _, + NoEndDelimiter = PsycParseRC::PSYC_PARSE_ERROR_END as _, + NoNewlineAfterMethod = PsycParseRC::PSYC_PARSE_ERROR_METHOD as _, + NoNewlineAfterModifier = PsycParseRC::PSYC_PARSE_ERROR_MOD_NL as _, + InvalidModifierLength = PsycParseRC::PSYC_PARSE_ERROR_MOD_LEN as _, + NoTabBeforeModifierValue = PsycParseRC::PSYC_PARSE_ERROR_MOD_TAB as _, + NoModifierName = PsycParseRC::PSYC_PARSE_ERROR_MOD_NAME as _, + NoNewlineAfterContentLength = PsycParseRC::PSYC_PARSE_ERROR_LENGTH as _, + GenericError = PsycParseRC::PSYC_PARSE_ERROR as _, +} +#[repr(C)] +#[derive(Debug, PartialEq)] +pub enum PsycListParserError { + NoElementLength = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_NO_LEN as _, + InvalidElementLength = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_LENGTH as _, + InvalidElementType = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_TYPE as _, + InvalidElementStart = PsycParseListRC::PSYC_PARSE_LIST_ERROR_ELEM_START as _, + InvalidType = PsycParseListRC::PSYC_PARSE_LIST_ERROR_TYPE as _, + GenericError = PsycParseListRC::PSYC_PARSE_LIST_ERROR as _, +} diff --git a/rust/src/uniform_types.rs b/rust/src/uniform_types.rs index 069a46a..c6bbab4 100644 --- a/rust/src/uniform_types.rs +++ b/rust/src/uniform_types.rs @@ -1,4 +1,4 @@ -use types::*; +use types::PsycString; #[derive(Debug, PartialEq)] pub enum PsycEntity<'a> { diff --git a/rust/tests/test_list_parser.rs b/rust/tests/test_list_parser.rs index 5c3ffb8..5c8e463 100644 --- a/rust/tests/test_list_parser.rs +++ b/rust/tests/test_list_parser.rs @@ -1,5 +1,5 @@ extern crate psyc; -use psyc::parser::*; +use psyc::*; #[test] fn test_parse() { diff --git a/rust/tests/test_parser.rs b/rust/tests/test_parser.rs index 3d43c30..c099ae3 100644 --- a/rust/tests/test_parser.rs +++ b/rust/tests/test_parser.rs @@ -1,5 +1,5 @@ extern crate psyc; -use psyc::parser::*; +use psyc::*; #[test] fn test_parse() {