mirror of https://github.com/dnomd343/ClearDNS
				
				
			
				 18 changed files with 275 additions and 168 deletions
			
			
		@ -1,12 +1,17 @@ | 
				
			|||
#pragma once | 
				
			|||
 | 
				
			|||
/* Generated with cbindgen:0.23.0 */ | 
				
			|||
 | 
				
			|||
#include <stdarg.h> | 
				
			|||
#include <stdbool.h> | 
				
			|||
#include <stdint.h> | 
				
			|||
#include <stdlib.h> | 
				
			|||
 | 
				
			|||
/**
 | 
				
			|||
 * Free the exported c-style string. | 
				
			|||
 */ | 
				
			|||
void free_rust_string(const char *ptr); | 
				
			|||
 | 
				
			|||
const char *to_json_ffi(const char *content); | 
				
			|||
/**
 | 
				
			|||
 * Format the input text into JSON format and return a c-style string, or return | 
				
			|||
 * `NULL` if an error occurs. | 
				
			|||
 */ | 
				
			|||
const char *to_json(const char *content); | 
				
			|||
 | 
				
			|||
@ -1,3 +1,3 @@ | 
				
			|||
language = "C" | 
				
			|||
pragma_once = true | 
				
			|||
include_version = true | 
				
			|||
include_version = false | 
				
			|||
 | 
				
			|||
@ -1,27 +1,130 @@ | 
				
			|||
use crate::json::to_json; | 
				
			|||
use std::ffi::{c_char, CStr, CString}; | 
				
			|||
use std::os::raw::c_char; | 
				
			|||
use std::ffi::{CStr, CString}; | 
				
			|||
use crate::parser::{parser, Value}; | 
				
			|||
 | 
				
			|||
fn to_c_string(string: String) -> *const c_char { // fetch c-style ptr of string
 | 
				
			|||
    CString::new(string).unwrap().into_raw() | 
				
			|||
/// Load c-style string from `const char *` pointer.
 | 
				
			|||
#[inline] | 
				
			|||
unsafe fn load_c_string(ptr: *const c_char) -> String { | 
				
			|||
    CString::from(CStr::from_ptr(ptr)) | 
				
			|||
        .into_string() | 
				
			|||
        .unwrap() | 
				
			|||
} | 
				
			|||
 | 
				
			|||
unsafe fn load_c_string(ptr: *const c_char) -> String { // load string from c-style ptr
 | 
				
			|||
    String::from( | 
				
			|||
        CStr::from_ptr(ptr).to_str().unwrap() | 
				
			|||
    ) | 
				
			|||
/// Export c-style string as `const char *` pointer.
 | 
				
			|||
/// # NOTE
 | 
				
			|||
/// The exported string cannot be freed by the c language `free(void *)` function,
 | 
				
			|||
/// but should use the `free_rust_string` callback function, if this interface is
 | 
				
			|||
/// not called, a memory leak will occur.
 | 
				
			|||
#[inline] | 
				
			|||
fn export_c_string(string: String) -> *const c_char { | 
				
			|||
    CString::new(string).unwrap().into_raw() | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/// Free the exported c-style string.
 | 
				
			|||
#[no_mangle] | 
				
			|||
pub unsafe extern "C" fn free_rust_string(ptr: *const c_char) { // free string memory
 | 
				
			|||
    let _ = CString::from_raw(ptr as *mut _); | 
				
			|||
pub unsafe extern "C" fn free_rust_string(ptr: *const c_char) { | 
				
			|||
    let _ = CString::from_raw(ptr as *mut _); // reclaim rust ownership
 | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/// Deserialize text content and serialize to JSON format.
 | 
				
			|||
fn json_format(content: &str) -> Option<String> { | 
				
			|||
    let result = match parser(&content) { | 
				
			|||
        Ok(value) => match value { | 
				
			|||
            Value::JSON(json) => serde_json::to_string(&json), | 
				
			|||
            Value::YAML(yaml) => serde_json::to_string(&yaml), | 
				
			|||
            Value::TOML(toml) => serde_json::to_string(&toml), | 
				
			|||
        }, | 
				
			|||
        _ => return None, | 
				
			|||
    }; | 
				
			|||
    match result { | 
				
			|||
        Ok(data) => Some(data), | 
				
			|||
        Err(_) => None, | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
/// Format the input text into JSON format and return a c-style string, or return
 | 
				
			|||
/// `NULL` if an error occurs.
 | 
				
			|||
#[no_mangle] | 
				
			|||
pub unsafe extern "C" fn to_json_ffi(content: *const c_char) -> *const c_char { | 
				
			|||
pub unsafe extern "C" fn to_json(content: *const c_char) -> *const c_char { | 
				
			|||
    let content = load_c_string(content); | 
				
			|||
    let result = match to_json(&content) { // convert to JSON format
 | 
				
			|||
        Some(data) => data, | 
				
			|||
        None => String::new(), // convert failed -> empty string
 | 
				
			|||
    }; | 
				
			|||
    to_c_string(result) // return c-style ptr
 | 
				
			|||
    match json_format(&content) { | 
				
			|||
        Some(data) => export_c_string(data), | 
				
			|||
        None => std::ptr::null(), | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
#[cfg(test)] | 
				
			|||
mod tests { | 
				
			|||
    use super::json_format; | 
				
			|||
 | 
				
			|||
    const JSON_TEST_STR: &str = r#" | 
				
			|||
{ | 
				
			|||
  "int": 123, | 
				
			|||
  "bool": true, | 
				
			|||
  "float": 3.141592, | 
				
			|||
  "string": "json test", | 
				
			|||
  "array": [1, 2, 3, 4, 5], | 
				
			|||
  "object": { | 
				
			|||
    "sub": "test" | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
"#; | 
				
			|||
 | 
				
			|||
    const YAML_TEST_STR: &str = r#" | 
				
			|||
int: 123 | 
				
			|||
bool: true | 
				
			|||
float: 3.141592 | 
				
			|||
string: "json test" | 
				
			|||
array: | 
				
			|||
 - 1 | 
				
			|||
 - 2 | 
				
			|||
 - 3 | 
				
			|||
 - 4 | 
				
			|||
 - 5 | 
				
			|||
object: | 
				
			|||
  sub: test | 
				
			|||
"#; | 
				
			|||
 | 
				
			|||
    const TOML_TEST_STR: &str = r#" | 
				
			|||
int = 123 | 
				
			|||
bool = true | 
				
			|||
float = 3.141592 | 
				
			|||
string = "json test" | 
				
			|||
array = [ 1, 2, 3, 4, 5 ] | 
				
			|||
 | 
				
			|||
[object] | 
				
			|||
sub = "test" | 
				
			|||
"#; | 
				
			|||
 | 
				
			|||
    #[inline] | 
				
			|||
    fn format(raw: &str) -> String { | 
				
			|||
        match json_format(raw) { | 
				
			|||
            Some(data) => data, | 
				
			|||
            None => panic!("format error"), | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    #[test] | 
				
			|||
    fn json_input() { | 
				
			|||
        assert_eq!( | 
				
			|||
            format(JSON_TEST_STR), | 
				
			|||
            format(&json_format(JSON_TEST_STR).unwrap()), | 
				
			|||
        ); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    #[test] | 
				
			|||
    fn yaml_input() { | 
				
			|||
        assert_eq!( | 
				
			|||
            format(JSON_TEST_STR), | 
				
			|||
            format(&json_format(YAML_TEST_STR).unwrap()), | 
				
			|||
        ); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    #[test] | 
				
			|||
    fn toml_input() { | 
				
			|||
        assert_eq!( | 
				
			|||
            format(JSON_TEST_STR), | 
				
			|||
            format(&json_format(TOML_TEST_STR).unwrap()), | 
				
			|||
        ); | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
@ -1,21 +0,0 @@ | 
				
			|||
use serde_json as json; | 
				
			|||
use crate::parser::{parser, Value}; | 
				
			|||
 | 
				
			|||
fn json_convert(content: &str) -> Result<String, String> { // convert to JSON format
 | 
				
			|||
    let data = match parser(content)? { | 
				
			|||
        Value::JSON(_json) => json::to_string(&_json), | 
				
			|||
        Value::YAML(_yaml) => json::to_string(&_yaml), | 
				
			|||
        Value::TOML(_toml) => json::to_string(&_toml), | 
				
			|||
    }; | 
				
			|||
    match data { | 
				
			|||
        Ok(data) => Ok(data), | 
				
			|||
        Err(err) => Err(err.to_string()), | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
 | 
				
			|||
pub fn to_json(content: &str) -> Option<String> { // to JSON string
 | 
				
			|||
    match json_convert(content) { | 
				
			|||
        Ok(data) => Some(data), | 
				
			|||
        Err(_) => None, // convert failed
 | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
@ -1,4 +1,2 @@ | 
				
			|||
mod ffi; | 
				
			|||
mod json; | 
				
			|||
mod tests; | 
				
			|||
mod parser; | 
				
			|||
 | 
				
			|||
@ -1,80 +0,0 @@ | 
				
			|||
use crate::json::to_json; | 
				
			|||
 | 
				
			|||
#[allow(dead_code)] | 
				
			|||
const JSON_TEST_CONTENT: &str = r#" | 
				
			|||
{ | 
				
			|||
  "int": 123, | 
				
			|||
  "bool": true, | 
				
			|||
  "float": 3.141592, | 
				
			|||
  "string": "json test", | 
				
			|||
  "array": [1, 2, 3, 4, 5], | 
				
			|||
  "object": { | 
				
			|||
    "sub": "test" | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
"#; | 
				
			|||
 | 
				
			|||
#[allow(dead_code)] | 
				
			|||
const YAML_TEST_CONTENT: &str = r#" | 
				
			|||
int: 123 | 
				
			|||
bool: true | 
				
			|||
float: 3.141592 | 
				
			|||
string: "json test" | 
				
			|||
array: | 
				
			|||
 - 1 | 
				
			|||
 - 2 | 
				
			|||
 - 3 | 
				
			|||
 - 4 | 
				
			|||
 - 5 | 
				
			|||
object: | 
				
			|||
  sub: test | 
				
			|||
"#; | 
				
			|||
 | 
				
			|||
#[allow(dead_code)] | 
				
			|||
const TOML_TEST_CONTENT: &str = r#" | 
				
			|||
int = 123 | 
				
			|||
bool = true | 
				
			|||
float = 3.141592 | 
				
			|||
string = "json test" | 
				
			|||
array = [ 1, 2, 3, 4, 5 ] | 
				
			|||
 | 
				
			|||
[object] | 
				
			|||
sub = "test" | 
				
			|||
"#; | 
				
			|||
 | 
				
			|||
 | 
				
			|||
mod tests { | 
				
			|||
    use super::*; | 
				
			|||
 | 
				
			|||
    #[allow(dead_code)] | 
				
			|||
    fn format_json(raw: &str) -> String { | 
				
			|||
        match to_json(raw) { | 
				
			|||
            Some(data) => data, | 
				
			|||
            None => panic!("JSON format error"), | 
				
			|||
        } | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    #[test] | 
				
			|||
    fn json_to_json() { | 
				
			|||
        assert_eq!( | 
				
			|||
            format_json(JSON_TEST_CONTENT), | 
				
			|||
            format_json(&to_json(JSON_TEST_CONTENT).unwrap()), | 
				
			|||
        ); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    #[test] | 
				
			|||
    fn yaml_to_json() { | 
				
			|||
        assert_eq!( | 
				
			|||
            format_json(JSON_TEST_CONTENT), | 
				
			|||
            format_json(&to_json(YAML_TEST_CONTENT).unwrap()), | 
				
			|||
        ); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    #[test] | 
				
			|||
    fn toml_to_json() { | 
				
			|||
        assert_eq!( | 
				
			|||
            format_json(JSON_TEST_CONTENT), | 
				
			|||
            format_json(&to_json(TOML_TEST_CONTENT).unwrap()), | 
				
			|||
        ); | 
				
			|||
    } | 
				
			|||
} | 
				
			|||
					Loading…
					
					
				
		Reference in new issue