Skip to content

Commit

Permalink
feat: serde deserialization support
Browse files Browse the repository at this point in the history
resolves #4. 🎉
  • Loading branch information
JakeStanger committed Nov 27, 2022
1 parent 4c69a12 commit 9fbf1b0
Show file tree
Hide file tree
Showing 12 changed files with 1,366 additions and 192 deletions.
28 changes: 18 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Unlike JSON or YAML or TOML, you cannot serialize code back into Corn.
### As a binary

Corn can be installed as an executable binary to convert files from the `.corn` format
into any supported output format. Currently these are:
into any supported output format. Currently, these are:

- JSON
- YAML
Expand Down Expand Up @@ -51,19 +51,26 @@ without needing to convert to other file formats.

[crate](https://crates.io/crates/libcorn) | [docs](https://docs.rs/libcorn/latest/libcorn)

The recommended way to do this is using `serde` into a struct:

```rust
use libcorn::parse;
use serde::Deserialize;

#[derive(Deserialize)]
struct Config {
foo: u8
}

fn main() {
let corn = "{foo = 42}";

let config = parse(corn).unwrap();
let json = serde_json::to_string_pretty(&config.value).unwrap();

assert_eq!(json, "{\"foo\": 42}");
let config = libcorn::from_str::<Config>(corn).unwrap();
assert_eq!(config.foo, 42);
}
```

You can also use `libcorn::parse` directly to get an AST representation of the config.
This can be serialized directly, which offers a faster route when converting to other formats.

A WASM version for use in NodeJS and browsers is also available.

> ⚠ Note when running under NodeJS you will require `--experimental-modules` for versions <= 16.
Expand All @@ -75,7 +82,7 @@ A WASM version for use in NodeJS and browsers is also available.
import * as corn from 'libcorn';

const parsed = corn.parse('{foo = "bar"}');
console.log(parsed.value) // { foo: "bar" }
console.log(parsed) // { foo: "bar" }
```

## Writing Corn
Expand All @@ -84,7 +91,8 @@ console.log(parsed.value) // { foo: "bar" }
All Corn files must contain a top-level object that contains keys/values.

Keys do not require quotes around them. The first character in the key cannot be whilespace, a number or any of the following characters: `. - " $ { [ =`.
Keys do not require quotes around them. The first character in the key cannot be whitespace,
a number or any of the following characters: `. - " $ { [ =`.
The remaining characters can be any unicode character except whitespace and the following: `. =`.


Expand Down Expand Up @@ -493,7 +501,7 @@ At the moment Corn is in very early stages. If you'd like to help out, I'd absol

### Running Tests

You must set `CORN_TEST=foobar` as this is required for the environment variable tests.
You must set `CORN_TEST=bar` as this is required for the environment variable tests.

### WASM

Expand Down
2 changes: 1 addition & 1 deletion corn-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
description = "CLI for Corn, A simple and pain-free configuration language."
repository = "https://github.com/JakeStanger/corn"
keywords = ["configuration", "language", "wasm", "pest", "peg", "cli"]
keywords = ["configuration", "language", "pest", "peg", "cli"]

[dependencies]
libcorn = { version = "0.4.0", path = "../libcorn" }
Expand Down
12 changes: 6 additions & 6 deletions corn-cli/src/bin/corn.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use corn_cli::error::{format_parser_err, print_err, Error, ExitCode};
use libcorn::error::FileReadError;
use libcorn::{parse, Config, TomlValue};
use libcorn::{parse, TomlValue, Value};
use std::fs::read_to_string;
use std::path::Path;
use std::process::exit;
Expand Down Expand Up @@ -70,24 +70,24 @@ fn get_output_type(arg: Option<OutputType>) -> OutputType {
OutputType::Json
}

fn serialize(config: Config, output_type: OutputType) -> Result<String, Error> {
fn serialize(config: Value, output_type: OutputType) -> Result<String, Error> {
match output_type {
OutputType::Json => {
let res = serde_json::to_string_pretty(&config.value);
let res = serde_json::to_string_pretty(&config);
match res {
Ok(str) => Ok(str),
Err(err) => Err(Error::Serializing(err.to_string())),
}
}
OutputType::Yaml => {
let res = serde_yaml::to_string(&config.value);
let res = serde_yaml::to_string(&config);
match res {
Ok(str) => Ok(str),
Err(err) => Err(Error::Serializing(err.to_string())),
}
}
OutputType::Toml => {
let toml_value = TomlValue::from(config.value);
let toml_value = TomlValue::from(config);
let res = toml::to_string_pretty(&toml_value);
match res {
Ok(str) => Ok(str),
Expand All @@ -104,7 +104,7 @@ fn handle_err(error: Error, unparsed_file: String, path: &Path) {
eprintln!("{} {}", code_formatted, error.to_string().bright_red());

if let Error::Corn(libcorn::error::Error::ParserError(err)) = error {
eprintln!("{}", format_parser_err(err, unparsed_file, path));
eprintln!("{}", format_parser_err(*err, unparsed_file, path));
};

exit(code);
Expand Down
9 changes: 8 additions & 1 deletion corn-cli/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use colored::*;
use libcorn::error::{Error as CornError, FileReadError, InputResolveError, SerializationError};
use libcorn::error::{
DeserializationError, Error as CornError, FileReadError, InputResolveError, SerializationError,
};
use libcorn::Rule;
use pest::error::{ErrorVariant, LineColLocation};
use std::fmt::{Display, Formatter};
Expand Down Expand Up @@ -38,6 +40,10 @@ impl ExitCode for SerializationError {
const EXIT_CODE: i32 = 4;
}

impl ExitCode for DeserializationError {
const EXIT_CODE: i32 = 5;
}

impl std::error::Error for Error {}

impl From<io::Error> for Error {
Expand Down Expand Up @@ -83,6 +89,7 @@ impl Error {
match self {
Error::Corn(CornError::ParserError(_)) => pest::error::Error::EXIT_CODE,
Error::Corn(CornError::InputResolveError(_)) => pest::error::Error::EXIT_CODE,
Error::Corn(CornError::DeserializationError(_)) => DeserializationError::EXIT_CODE,
Error::ReadingFile(_) => FileReadError::EXIT_CODE,
Error::Serializing(_) => SerializationError::EXIT_CODE,
}
Expand Down
Loading

0 comments on commit 9fbf1b0

Please sign in to comment.