mirror of https://github.com/dnomd343/ClearDNS
Dnomd343
2 years ago
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
|
|||
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 => String::new(), // convert failed -> empty string
|
|||
}; |
|||
to_c_string(result) // return c-style ptr
|
|||
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