mirror of https://github.com/dnomd343/ClearDNS
Dnomd343
2 years ago
10 changed files with 178 additions and 51 deletions
@ -0,0 +1,20 @@ |
|||||
|
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) => serde_json::to_string(&json), |
||||
|
Value::YAML(yaml) => serde_json::to_string(&yaml), |
||||
|
Value::TOML(toml) => serde_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, |
||||
|
} |
||||
|
} |
@ -1,14 +1,27 @@ |
|||||
|
use crate::convert::to_json; |
||||
use std::ffi::{c_char, CStr, CString}; |
use std::ffi::{c_char, CStr, CString}; |
||||
use crate::json::to_json; |
|
||||
|
fn to_c_string(string: String) -> *const c_char { // fetch c-style ptr of string
|
||||
|
CString::new(string).unwrap().into_raw() |
||||
|
} |
||||
|
|
||||
|
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() |
||||
|
) |
||||
|
} |
||||
|
|
||||
#[no_mangle] |
#[no_mangle] |
||||
pub unsafe extern "C" fn free_rust_string(string: *const c_char) { |
pub unsafe extern "C" fn free_rust_string(ptr: *const c_char) { // free string memory
|
||||
let _ = CString::from_raw(string as *mut _); |
let _ = CString::from_raw(ptr as *mut _); |
||||
} |
} |
||||
|
|
||||
#[no_mangle] |
#[no_mangle] |
||||
pub unsafe extern "C" fn to_json_rust(content: *const c_char) -> *const c_char { |
pub unsafe extern "C" fn to_json_ffi(content: *const c_char) -> *const c_char { |
||||
let content: &str = CStr::from_ptr(content).to_str().unwrap(); |
let content = load_c_string(content); |
||||
let content: String = to_json(content); // may return empty string
|
let result = match to_json(&content) { // convert to JSON format
|
||||
CString::new(content).unwrap().into_raw() |
Some(data) => data, |
||||
|
None => String::new(), // convert failed -> empty string
|
||||
|
}; |
||||
|
to_c_string(result) // return c-style ptr
|
||||
} |
} |
||||
|
@ -1,32 +0,0 @@ |
|||||
use serde_json as json; |
|
||||
use serde_yaml as yaml; |
|
||||
|
|
||||
enum Format { |
|
||||
JSON(json::Value), |
|
||||
YAML(yaml::Value), |
|
||||
TOML(toml::Value), |
|
||||
} |
|
||||
|
|
||||
fn parser(content: &str) -> Option<Format> { |
|
||||
if let Ok(data) = json::from_str::<json::Value>(content) { // try JSON format
|
|
||||
return Some(Format::JSON(data)); |
|
||||
} |
|
||||
if let Ok(data) = toml::from_str::<toml::Value>(content) { // try TOML format
|
|
||||
return Some(Format::TOML(data)); |
|
||||
} |
|
||||
if let Ok(data) = yaml::from_str::<yaml::Value>(content) { // try YAML format
|
|
||||
return Some(Format::YAML(data)); |
|
||||
} |
|
||||
return None; // parse failed
|
|
||||
} |
|
||||
|
|
||||
pub fn to_json(content: &str) -> String { // convert to JSON format
|
|
||||
match parser(content) { |
|
||||
Some(data) => match data { |
|
||||
Format::JSON(dat) => json::to_string(&dat).unwrap(), |
|
||||
Format::YAML(dat) => json::to_string(&dat).unwrap(), |
|
||||
Format::TOML(dat) => json::to_string(&dat).unwrap(), |
|
||||
}, |
|
||||
None => String::from(""), // failed -> empty string
|
|
||||
} |
|
||||
} |
|
@ -1,2 +1,4 @@ |
|||||
mod ffi; |
mod ffi; |
||||
mod json; |
mod tests; |
||||
|
mod parser; |
||||
|
mod convert; |
||||
|
@ -0,0 +1,43 @@ |
|||||
|
use serde_json as json; |
||||
|
use serde_yaml as yaml; |
||||
|
|
||||
|
#[derive(Debug)] |
||||
|
pub enum Value { |
||||
|
JSON(json::Value), |
||||
|
YAML(yaml::Value), |
||||
|
TOML(toml::Value), |
||||
|
} |
||||
|
|
||||
|
fn json_parser(content: &str) -> Option<json::Value> { // parse json content
|
||||
|
match json::from_str::<json::Value>(content) { |
||||
|
Ok(result) => Some(result), |
||||
|
Err(_) => None, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
fn yaml_parser(content: &str) -> Option<yaml::Value> { // parse yaml content
|
||||
|
match yaml::from_str::<yaml::Value>(content) { |
||||
|
Ok(result) => Some(result), |
||||
|
Err(_) => None, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
fn toml_parser(content: &str) -> Option<toml::Value> { // parse toml content
|
||||
|
match toml::from_str::<toml::Value>(content) { |
||||
|
Ok(result) => Some(result), |
||||
|
Err(_) => None, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
pub fn parser(content: &str) -> Result<Value, String> { |
||||
|
match json_parser(content) { // try JSON format
|
||||
|
Some(data) => Ok(Value::JSON(data)), |
||||
|
None => match toml_parser(content) { // try TOML format
|
||||
|
Some(data) => Ok(Value::TOML(data)), |
||||
|
None => match yaml_parser(content) { // try YAML format
|
||||
|
Some(data) => Ok(Value::YAML(data)), |
||||
|
None => Err(String::from("unknown input format")), |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,80 @@ |
|||||
|
use crate::convert::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