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 |
#pragma once |
||||
|
|
||||
/* Generated with cbindgen:0.23.0 */ |
|
||||
|
|
||||
#include <stdarg.h> |
#include <stdarg.h> |
||||
#include <stdbool.h> |
#include <stdbool.h> |
||||
#include <stdint.h> |
#include <stdint.h> |
||||
#include <stdlib.h> |
#include <stdlib.h> |
||||
|
|
||||
|
/**
|
||||
|
* Free the exported c-style string. |
||||
|
*/ |
||||
void free_rust_string(const char *ptr); |
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" |
language = "C" |
||||
pragma_once = true |
pragma_once = true |
||||
include_version = true |
include_version = false |
||||
|
@ -1,27 +1,130 @@ |
|||||
use crate::json::to_json; |
use std::os::raw::c_char; |
||||
use std::ffi::{c_char, CStr, CString}; |
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
|
/// Load c-style string from `const char *` pointer.
|
||||
CString::new(string).unwrap().into_raw() |
#[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
|
/// Export c-style string as `const char *` pointer.
|
||||
String::from( |
/// # NOTE
|
||||
CStr::from_ptr(ptr).to_str().unwrap() |
/// 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] |
#[no_mangle] |
||||
pub unsafe extern "C" fn free_rust_string(ptr: *const c_char) { // free string memory
|
pub unsafe extern "C" fn free_rust_string(ptr: *const c_char) { |
||||
let _ = CString::from_raw(ptr as *mut _); |
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] |
#[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 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, |
Some(data) => data, |
||||
None => String::new(), // convert failed -> empty string
|
None => panic!("format error"), |
||||
}; |
} |
||||
to_c_string(result) // return c-style ptr
|
} |
||||
|
|
||||
|
#[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 ffi; |
||||
mod json; |
|
||||
mod tests; |
|
||||
mod parser; |
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