Browse Source

Merge branch 'dev'

dev
Dnomd343 2 years ago
parent
commit
310264e15b
  1. 4
      include/to_json.h
  2. 5
      src/common/json.c
  3. 12
      src/to-json/Cargo.lock
  4. 2
      src/to-json/Cargo.toml
  5. 20
      src/to-json/src/convert.rs
  6. 27
      src/to-json/src/ffi.rs
  7. 32
      src/to-json/src/json.rs
  8. 4
      src/to-json/src/lib.rs
  9. 43
      src/to-json/src/parser.rs
  10. 80
      src/to-json/src/tests.rs

4
include/to_json.h

@ -7,6 +7,6 @@
#include <stdint.h>
#include <stdlib.h>
void free_rust_string(const char *string);
void free_rust_string(const char *ptr);
const char *to_json_rust(const char *content);
const char *to_json_ffi(const char *content);

5
src/common/json.c

@ -17,8 +17,8 @@ uint8_t is_json_suffix(const char *file_name) { // whether file name end with `.
return FALSE;
}
char* to_json(const char *content) { // convert JSON / TOML / YAML to json format (if failed -> return NULL)
const char *json_string = to_json_rust(content); // convert to json format
char* to_json(const char *content) { // convert JSON / TOML / YAML to json format (failed -> NULL)
const char *json_string = to_json_ffi(content); // convert to json format
char *json_content = strdup(json_string); // load string into owner heap
free_rust_string(json_string); // free rust string
if (strlen(json_content) == 0) { // empty string -> convert error
@ -30,6 +30,7 @@ char* to_json(const char *content) { // convert JSON / TOML / YAML to json forma
return json_content;
}
cJSON* json_field_get(cJSON *entry, const char *key) { // fetch key from json map (create when key not exist)
cJSON *sub = entry->child;
while (sub != NULL) { // traverse all keys

12
src/to-json/Cargo.lock

@ -16,9 +16,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "indexmap"
version = "1.9.1"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
@ -38,15 +38,15 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "serde"
version = "1.0.147"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
[[package]]
name = "serde_json"
version = "1.0.87"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
dependencies = [
"itoa",
"ryu",

2
src/to-json/Cargo.toml

@ -9,6 +9,6 @@ crate-type = ["staticlib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde_json = "1.0.87"
serde_json = "1.0.89"
serde_yaml = "0.9.14"
toml = "0.5.9"

20
src/to-json/src/convert.rs

@ -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,
}
}

27
src/to-json/src/ffi.rs

@ -1,14 +1,27 @@
use crate::convert::to_json;
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]
pub unsafe extern "C" fn free_rust_string(string: *const c_char) {
let _ = CString::from_raw(string as *mut _);
pub unsafe extern "C" fn free_rust_string(ptr: *const c_char) { // free string memory
let _ = CString::from_raw(ptr as *mut _);
}
#[no_mangle]
pub unsafe extern "C" fn to_json_rust(content: *const c_char) -> *const c_char {
let content: &str = CStr::from_ptr(content).to_str().unwrap();
let content: String = to_json(content); // may return empty string
CString::new(content).unwrap().into_raw()
pub unsafe extern "C" fn to_json_ffi(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
}

32
src/to-json/src/json.rs

@ -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
}
}

4
src/to-json/src/lib.rs

@ -1,2 +1,4 @@
mod ffi;
mod json;
mod tests;
mod parser;
mod convert;

43
src/to-json/src/parser.rs

@ -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")),
}
}
}
}

80
src/to-json/src/tests.rs

@ -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…
Cancel
Save