Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
mod test {
use super::{data, Data, Value};
#[test]
fn data_macro() {
let x: i64 = -1234567890;
let s = "string".to_string();
let mut d = data!({
"thing": 2,
"other thing": [&s, 1.666, x, true, {"nested array": [{}, []]}],
"last thing": null
});
// to_json()
assert_eq!(
d.to_json().unwrap(),
"{\"thing\":2,\"other thing\":[\"string\",1.666,-1234567890,true,{\"nested array\":[{},[]]}],\"last thing\":null}"
);
// query/indexing
assert_eq!(d["thing"], d[0]); // we can index into an object with an integer or string key
assert_ne!(d["thing"], d[1]);
// display
assert_eq!(format!("{}", d["thing"]), "2");
// data extraction
assert_eq!(d["last thing"], Value::Null);
assert_eq!(d["other thing"][3].to_bool(), true);
assert_eq!(d["thing"].to_i64(), 2);
assert_eq!(d["other thing"][1].to_f64(), 1.666);
assert_eq!(d["other thing"][0].to_string(), "string");
assert_eq!(d["other thing"][4]["nested array"][1].to_vec(), vec![]);
assert_eq!(d["other thing"][4]["nested array"][0].to_map(), indexmap::IndexMap::new());
// mutability
d["thing"] = data!({"something more complex": {"key": 987654321 }});
assert_eq!(
d.to_json().unwrap(),
"{\"thing\":{\"something more complex\":{\"key\":987654321}},\"other thing\":[\"string\",1.666,-1234567890,true,{\"nested array\":[{},[]]}],\"last thing\":null}"
);
// serde_json parsing interop
let v: serde_json::Value = serde_json::from_str(&d.to_json().unwrap()).unwrap();
let d2 = Value::from(&v);
assert_eq!(d.to_json().unwrap(), d2.to_json().unwrap());
}
}
I was thinking it would be useful to have such a structure in Rust for things like KEDs and SADs and now that I've built the core of it, once `cesride` is complete it should be trivial to implement `.to_cesr()` and `.to_cesrb()`. I was thinking since this complements parsing logic, all this probably wants to live in `parside`. Any objections to me starting work on spiking out `parside` and spiking out an integration with `cesride`?
Number of replies: 22
Number of replies: 0
data!({"foo": "bar"})
is valid.
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
mod core;
mod data;
mod error;
pub struct Parser;
macro_rules! boxed {
($e:expr) => { Box::into_raw(Box::new($e)) }
}
#[no_mangle]
pub unsafe extern "C" fn parside_parser_new() -> *mut Parser {
boxed!(Parser {})
}
#[no_mangle]
pub unsafe extern "C" fn parside_inhale(
ser: *const libc::c_uchar,
ser_sz: libc::size_t,
parser: *const Parser,
) -> libc::c_int {
if parser.is_null() || ser.is_null() {
return 1;
}
// convert ser into octet string
let ser = unsafe {
std::slice::from_raw_parts(ser, ser_sz)
};
// grab parser from opaque pointer
let mut parser = unsafe {
&*parser
};
// parse octet string
parser.inhale(ser)?;
return 0;
}
#[no_mangle]
pub unsafe extern "C" fn parside_next(
parser: *const Parser
) -> *mut Value {
let parser = unsafe {
assert!(!parser.is_null());
&*parser
};
boxed!(parser.next())
}
#[no_mangle]
pub unsafe extern "C" fn parside_free(
object: *mut libc::c_void
) {
if !object.is_null() { unsafe {
Box::from_raw(object);
}}
}
this is a start, i wrote it up in a few minutes so it won't compile but it shows you the idea. generally i like returning an int to indicate success or a failure code and dealing with all returned data as inout params, but that's not exactly the example I am showing here
Number of replies: 0
❯ cat header.h
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct Parser Parser;
void parser_free(struct Parser *parser);
struct Parser *parser_new(void);
int parser_inhale(const unsigned char *ser, size_t ser_sz, struct Parser *parser);
int parser_next(const struct Parser *parser);
❯ cat main.c
#include "header.h"
int main(int argc, char *argv[]) {
unsigned char s[] = "test string";
Parser* parser = parser_new();
parser_inhale(s, 11, parser);
parser_next(parser);
parser_free(parser);
return 0;
}
❯ clang main.c -o main -L target/release -l saidide
❯ ./main
test stringNumber of replies: 0
pub struct Parser {
data: String
}
impl Parser {
pub fn inhale(&mut self, ser: &[u8]) {
self.data = std::str::from_utf8(ser).unwrap().to_string();
}
pub fn dump(&self) {
println!("{}", self.data);
}
}
#[no_mangle]
pub extern "C" fn parser_free(parser: *mut Parser) {
unsafe { drop(opaque_pointer::own_back(parser)) };
}
#[no_mangle]
pub extern "C" fn parser_new() -> *mut Parser {
opaque_pointer::raw(Parser { data: "data".to_string() })
}
#[no_mangle]
pub unsafe extern "C" fn parser_inhale(
ser: *const libc::c_uchar,
ser_sz: libc::size_t,
parser: *mut Parser,
) -> libc::c_int {
if parser.is_null() || ser.is_null() {
return 1;
}
// convert ser into octet string
let ser = unsafe {
std::slice::from_raw_parts(ser, ser_sz)
};
// grab parser from opaque pointer
let parser = unsafe {
match opaque_pointer::mut_object(parser) {
Ok(p) => p,
Err(_) => { return 1; },
}
};
// parse octet string
parser.inhale(ser);
return 0;
}
#[no_mangle]
pub unsafe extern "C" fn parser_next(
parser: *const Parser
) -> libc::c_int {
if parser.is_null() {
return 1;
}
let parser = unsafe {
match opaque_pointer::object(parser) {
Ok(p) => p,
Err(_) => { return 1; },
}
};
parser.dump();
return 0;
}Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
❯ make python-shell Python 3.10.6 (main, Aug 11 2022, 13:49:25) [Clang 13.1.6 (clang-1316.0.21.2.5)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from cesride import Matter >>> m = Matter(qb64="BGlOiUdp5sMmfotHfCWQKEzWR91C72AH0lT84c0um-Qj") >>> qb2 = m.qb2() >>> print(qb2) [4, 105, 78, 137, 71, 105, 230, 195, 38, 126, 139, 71, 124, 37, 144, 40, 76, 214, 71, 221, 66, 239, 96, 7, 210, 84, 252, 225, 205, 46, 155, 228, 35] >>> m2 = Matter(qb2=bytes(qb2)) >>> m2.qb64() 'BGlOiUdp5sMmfotHfCWQKEzWR91C72AH0lT84c0um-Qj' >>>
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 6
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 0
Number of replies: 1
Number of replies: 0
Number of replies: 0