Fork me on GitHub
#other-languages
<
2022-04-06
>
Martynas Maciulevičius09:04:08

Does anyone know any C# libraries that allow to serialize into EDN? I found this but it doesn't seem to serialize: https://www.nuget.org/packages?q=extensible+data+notation https://www.nuget.org/packages/EdnParser/

emccue14:04:06

I started doodling on making a C layer for my rust library for it

emccue14:04:07

use std::ffi::{CStr, CString};
use libc;
use edn_format;
use edn_format::{ParserErrorWithContext, Value};

#[no_mangle]
pub extern "C" fn edn_integer_new(value: libc::c_long) -> *mut edn_format::Value {
    Box::into_raw(Box::new(edn_format::Value::Integer(value as i64)))
}

#[no_mangle]
pub extern "C" fn edn_string_new(value: *const libc::c_char) -> *mut edn_format::Value {
    let c_string = unsafe { CStr::from_ptr(value) };
    Box::into_raw(Box::new(edn_format::Value::String(
        c_string
            .to_str()
            .unwrap()
            .to_string()
    )))
}

#[no_mangle]
pub extern "C" fn edn_value_free(value: *mut edn_format::Value) {
    if !value.is_null() {
        unsafe { Box::from_raw(value); }
    }
}


#[no_mangle]
pub extern "C" fn edn_parse(value: *const libc::c_char, out: *mut *mut edn_format::Value) -> libc::c_int {
    let c_string = unsafe { CStr::from_ptr(value) };
    let str = c_string
        .to_str()
        .unwrap();
    let parse = edn_format::parse_str(str);
    match parse {
        Ok(value) => {
            unsafe { *out = Box::into_raw(Box::new(value)) };
            0
        }
        Err(_) => {
            -1
        }
    }
}

#[no_mangle]
pub extern "C" fn edn_display(value: *const edn_format::Value) {
    println!("{}", edn_format::emit_str(unsafe { value.as_ref().unwrap() }))
}

emccue14:04:34

you should be able to bind to this in C#

emccue14:04:29

>>> from ctypes import *
>>> dll = cdll.LoadLibrary("libedn_format_c.dylib")
>>> dll.edn_string_new.argtypes = [ c_char_p ]
>>> dll.edn_string_new.restype = c_void_p
>>> dll.edn_display.argtypes = [ c_void_p ]
>>> dll.edn_display.restype = None
>>> s = dll.edn_string_new(b"abc")
>>> dll.edn_display(s)
"abc"

Martynas Maciulevičius15:04:16

Yes but what I was looking for is something ready-made 😄 But thanks ;D

emccue15:04:19

>>> timeit.timeit(lambda: dll.edn_parse(b"{:a 12 :abc [1 2 {:a 3}]}"), number=10000) / 10000
3.068520799999419e-06

emccue15:04:34

in case anyone wants a blisteringly fast edn parser at some point

Cora (she/her)15:04:36

which language?

emccue15:04:27

just wrapping the rust one i wrote a few months ago

emccue15:04:58

so presumably it can be massaged into most languages