Skip to content

Commit

Permalink
Merge pull request #469 from polarathene/chore/common-parser-root-check
Browse files Browse the repository at this point in the history
chore: Use a common method in parsers to check root is a table
  • Loading branch information
matthiasbeyer committed Oct 7, 2023
2 parents 8e9fc52 + a5e6e57 commit 55c464e
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 40 deletions.
8 changes: 2 additions & 6 deletions src/file/format/json.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::error::Error;

use crate::format;
use crate::map::Map;
use crate::value::{Value, ValueKind};

Expand All @@ -8,13 +9,8 @@ pub fn parse(
text: &str,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
// Parse a JSON object value from the text
// TODO: Have a proper error fire if the root of a file is ever not a Table
let value = from_json_value(uri, &serde_json::from_str(text)?);
match value.kind {
ValueKind::Table(map) => Ok(map),

_ => Ok(Map::new()),
}
format::extract_root_table(uri, value)
}

fn from_json_value(uri: Option<&String>, value: &serde_json::Value) -> Value {
Expand Down
18 changes: 3 additions & 15 deletions src/file/format/json5.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::error::Error;

use crate::error::{ConfigError, Unexpected};
use crate::format;
use crate::map::Map;
use crate::value::{Value, ValueKind};

Expand All @@ -20,20 +20,8 @@ pub fn parse(
uri: Option<&String>,
text: &str,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
match json5_rs::from_str::<Val>(text)? {
Val::String(ref value) => Err(Unexpected::Str(value.clone())),
Val::Integer(value) => Err(Unexpected::I64(value)),
Val::Float(value) => Err(Unexpected::Float(value)),
Val::Boolean(value) => Err(Unexpected::Bool(value)),
Val::Array(_) => Err(Unexpected::Seq),
Val::Null => Err(Unexpected::Unit),
Val::Object(o) => match from_json5_value(uri, Val::Object(o)).kind {
ValueKind::Table(map) => Ok(map),
_ => Ok(Map::new()),
},
}
.map_err(|err| ConfigError::invalid_root(uri, err))
.map_err(|err| Box::new(err) as Box<dyn Error + Send + Sync>)
let value = from_json5_value(uri, json5_rs::from_str::<Val>(text)?);
format::extract_root_table(uri, value)
}

fn from_json5_value(uri: Option<&String>, value: Val) -> Value {
Expand Down
7 changes: 2 additions & 5 deletions src/file/format/ron.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::error::Error;

use crate::format;
use crate::map::Map;
use crate::value::{Value, ValueKind};

Expand All @@ -8,11 +9,7 @@ pub fn parse(
text: &str,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
let value = from_ron_value(uri, ron::from_str(text)?)?;
match value.kind {
ValueKind::Table(map) => Ok(map),

_ => Ok(Map::new()),
}
format::extract_root_table(uri, value)
}

fn from_ron_value(
Expand Down
10 changes: 3 additions & 7 deletions src/file/format/toml.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
use std::error::Error;

use crate::format;
use crate::map::Map;
use crate::value::{Value, ValueKind};
use crate::value::Value;

pub fn parse(
uri: Option<&String>,
text: &str,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
// Parse a TOML value from the provided text
// TODO: Have a proper error fire if the root of a file is ever not a Table
let value = from_toml_value(uri, &toml::from_str(text)?);
match value.kind {
ValueKind::Table(map) => Ok(map),

_ => Ok(Map::new()),
}
format::extract_root_table(uri, value)
}

fn from_toml_value(uri: Option<&String>, value: &toml::Value) -> Value {
Expand Down
8 changes: 2 additions & 6 deletions src/file/format/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::mem;

use yaml_rust as yaml;

use crate::format;
use crate::map::Map;
use crate::value::{Value, ValueKind};

Expand All @@ -21,13 +22,8 @@ pub fn parse(
}
};

// TODO: Have a proper error fire if the root of a file is ever not a Table
let value = from_yaml_value(uri, &root)?;
match value.kind {
ValueKind::Table(map) => Ok(map),

_ => Ok(Map::new()),
}
format::extract_root_table(uri, value)
}

fn from_yaml_value(
Expand Down
25 changes: 24 additions & 1 deletion src/format.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::error::Error;

use crate::{map::Map, value::Value};
use crate::error::{ConfigError, Unexpected};
use crate::map::Map;
use crate::value::{Value, ValueKind};

/// Describes a format of configuration source data
///
Expand All @@ -21,3 +23,24 @@ pub trait Format {
text: &str,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>>;
}

// Have a proper error fire if the root of a file is ever not a Table
pub fn extract_root_table(
uri: Option<&String>,
value: Value,
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
match value.kind {
ValueKind::Table(map) => Ok(map),
ValueKind::Nil => Err(Unexpected::Unit),
ValueKind::Array(_value) => Err(Unexpected::Seq),
ValueKind::Boolean(value) => Err(Unexpected::Bool(value)),
ValueKind::I64(value) => Err(Unexpected::I64(value)),
ValueKind::I128(value) => Err(Unexpected::I128(value)),
ValueKind::U64(value) => Err(Unexpected::U64(value)),
ValueKind::U128(value) => Err(Unexpected::U128(value)),
ValueKind::Float(value) => Err(Unexpected::Float(value)),
ValueKind::String(value) => Err(Unexpected::Str(value)),
}
.map_err(|err| ConfigError::invalid_root(uri, err))
.map_err(|err| Box::new(err) as Box<dyn Error + Send + Sync>)
}

0 comments on commit 55c464e

Please sign in to comment.