summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Orchard <if_coding@fastmail.com>2021-07-28 22:52:15 -0700
committerDavid Orchard <if_coding@fastmail.com>2021-08-15 10:31:18 -0700
commitfc8cf0ed674cbb495df1baff34d4b832ca5fad3c (patch)
treea83c82ff11399ebd2da8d7ae58da31b7f295998c /src
parent62c84297e5340d717d89c5c0b36ed86dd5ad9d2f (diff)
Use LinkedHashMap in place of HashMap
Diffstat (limited to 'src')
-rw-r--r--src/builder.rs23
-rw-r--r--src/config.rs12
-rw-r--r--src/de.rs5
-rw-r--r--src/env.rs6
-rw-r--r--src/file/format/hjson.rs8
-rw-r--r--src/file/format/ini.rs8
-rw-r--r--src/file/format/json.rs8
-rw-r--r--src/file/format/json5.rs8
-rw-r--r--src/file/format/mod.rs8
-rw-r--r--src/file/format/ron.rs8
-rw-r--r--src/file/format/toml.rs8
-rw-r--r--src/file/format/yaml.rs8
-rw-r--r--src/file/mod.rs6
-rw-r--r--src/path/mod.rs10
-rw-r--r--src/source.rs22
-rw-r--r--src/value.rs10
16 files changed, 80 insertions, 78 deletions
diff --git a/src/builder.rs b/src/builder.rs
index bb88f44..65f49ae 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -1,5 +1,6 @@
+use linked_hash_map::LinkedHashMap;
+use std::iter::IntoIterator;
use std::str::FromStr;
-use std::{collections::HashMap, iter::IntoIterator};
use crate::error::Result;
use crate::source::AsyncSource;
@@ -87,8 +88,8 @@ use crate::{config::Config, path::Expression, source::Source, value::Value};
/// ```
#[derive(Debug, Clone, Default)]
pub struct ConfigBuilder<St: BuilderState> {
- defaults: HashMap<Expression, Value>,
- overrides: HashMap<Expression, Value>,
+ defaults: LinkedHashMap<Expression, Value>,
+ overrides: LinkedHashMap<Expression, Value>,
state: St,
}
@@ -120,8 +121,8 @@ pub struct DefaultState {
/// Refer to [`ConfigBuilder`] for similar API sample usage or to the examples folder of the crate, where such a source is implemented.
#[derive(Debug, Clone, Default)]
pub struct AsyncConfigBuilder {
- defaults: HashMap<Expression, Value>,
- overrides: HashMap<Expression, Value>,
+ defaults: LinkedHashMap<Expression, Value>,
+ overrides: LinkedHashMap<Expression, Value>,
sources: Vec<SourceType>,
}
@@ -244,11 +245,11 @@ impl ConfigBuilder<DefaultState> {
}
fn build_internal(
- defaults: HashMap<Expression, Value>,
- overrides: HashMap<Expression, Value>,
+ defaults: LinkedHashMap<Expression, Value>,
+ overrides: LinkedHashMap<Expression, Value>,
sources: &[Box<dyn Source + Send + Sync>],
) -> Result<Config> {
- let mut cache: Value = HashMap::<String, Value>::new().into();
+ let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
// Add defaults
for (key, val) in defaults.into_iter() {
@@ -322,11 +323,11 @@ impl ConfigBuilder<AsyncState> {
}
async fn build_internal(
- defaults: HashMap<Expression, Value>,
- overrides: HashMap<Expression, Value>,
+ defaults: LinkedHashMap<Expression, Value>,
+ overrides: LinkedHashMap<Expression, Value>,
sources: &[SourceType],
) -> Result<Config> {
- let mut cache: Value = HashMap::<String, Value>::new().into();
+ let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
// Add defaults
for (key, val) in defaults.into_iter() {
diff --git a/src/config.rs b/src/config.rs
index b9c64b4..6302c45 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::fmt::Debug;
use crate::builder::{ConfigBuilder, DefaultState};
@@ -16,8 +16,8 @@ use crate::value::{Table, Value};
/// them according to the source's priority.
#[derive(Clone, Debug)]
pub struct Config {
- defaults: HashMap<path::Expression, Value>,
- overrides: HashMap<path::Expression, Value>,
+ defaults: LinkedHashMap<path::Expression, Value>,
+ overrides: LinkedHashMap<path::Expression, Value>,
sources: Vec<Box<dyn Source + Send + Sync>>,
/// Root of the cached configuration.
@@ -83,7 +83,7 @@ impl Config {
#[deprecated(since = "0.12.0", note = "please use 'ConfigBuilder' instead")]
pub fn refresh(&mut self) -> Result<&mut Config> {
self.cache = {
- let mut cache: Value = HashMap::<String, Value>::new().into();
+ let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
// Add defaults
for (key, val) in self.defaults.iter() {
@@ -181,7 +181,7 @@ impl Config {
self.get(key).and_then(Value::into_bool)
}
- pub fn get_table(&self, key: &str) -> Result<HashMap<String, Value>> {
+ pub fn get_table(&self, key: &str) -> Result<LinkedHashMap<String, Value>> {
self.get(key).and_then(Value::into_table)
}
@@ -212,7 +212,7 @@ impl Source for Config {
Box::new((*self).clone())
}
- fn collect(&self) -> Result<HashMap<String, Value>> {
+ fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
self.cache.clone().into_table()
}
}
diff --git a/src/de.rs b/src/de.rs
index a7a6fb4..7d66896 100644
--- a/src/de.rs
+++ b/src/de.rs
@@ -1,4 +1,5 @@
-use std::collections::{HashMap, VecDeque};
+use linked_hash_map::LinkedHashMap;
+use std::collections::VecDeque;
use std::iter::Enumerate;
use serde::de;
@@ -199,7 +200,7 @@ struct MapAccess {
}
impl MapAccess {
- fn new(table: HashMap<String, Value>) -> Self {
+ fn new(table: LinkedHashMap<String, Value>) -> Self {
MapAccess {
elements: table.into_iter().collect(),
}
diff --git a/src/env.rs b/src/env.rs
index 3d95e17..2e48701 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::env;
use crate::error::*;
@@ -79,8 +79,8 @@ impl Source for Environment {
Box::new((*self).clone())
}
- fn collect(&self) -> Result<HashMap<String, Value>> {
- let mut m = HashMap::new();
+ fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
+ let mut m = LinkedHashMap::new();
let uri: String = "the environment".into();
let separator = self.separator.as_deref().unwrap_or("");
diff --git a/src/file/format/hjson.rs b/src/file/format/hjson.rs
index f94b1d3..a61afef 100644
--- a/src/file/format/hjson.rs
+++ b/src/file/format/hjson.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use crate::value::{Value, ValueKind};
@@ -6,14 +6,14 @@ use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<LinkedHashMap<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_hjson_value(uri, &serde_hjson::from_str(text)?);
match value.kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(HashMap::new()),
+ _ => Ok(LinkedHashMap::new()),
}
}
@@ -30,7 +30,7 @@ fn from_hjson_value(uri: Option<&String>, value: &serde_hjson::Value) -> Value {
serde_hjson::Value::Bool(value) => Value::new(uri, ValueKind::Boolean(value)),
serde_hjson::Value::Object(ref table) => {
- let mut m = HashMap::new();
+ let mut m = LinkedHashMap::new();
for (key, value) in table {
m.insert(key.clone(), from_hjson_value(uri, value));
diff --git a/src/file/format/ini.rs b/src/file/format/ini.rs
index b45695a..47f3499 100644
--- a/src/file/format/ini.rs
+++ b/src/file/format/ini.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use ini::Ini;
@@ -8,13 +8,13 @@ use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
- let mut map: HashMap<String, Value> = HashMap::new();
+) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+ let mut map: LinkedHashMap<String, Value> = LinkedHashMap::new();
let i = Ini::load_from_str(text)?;
for (sec, prop) in i.iter() {
match sec {
Some(sec) => {
- let mut sec_map: HashMap<String, Value> = HashMap::new();
+ let mut sec_map: LinkedHashMap<String, Value> = LinkedHashMap::new();
for (k, v) in prop.iter() {
sec_map.insert(
k.to_owned(),
diff --git a/src/file/format/json.rs b/src/file/format/json.rs
index 87a6e61..a6a9443 100644
--- a/src/file/format/json.rs
+++ b/src/file/format/json.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use crate::value::{Value, ValueKind};
@@ -6,14 +6,14 @@ use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<LinkedHashMap<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(HashMap::new()),
+ _ => Ok(LinkedHashMap::new()),
}
}
@@ -34,7 +34,7 @@ fn from_json_value(uri: Option<&String>, value: &serde_json::Value) -> Value {
serde_json::Value::Bool(value) => Value::new(uri, ValueKind::Boolean(value)),
serde_json::Value::Object(ref table) => {
- let mut m = HashMap::new();
+ let mut m = LinkedHashMap::new();
for (key, value) in table {
m.insert(key.clone(), from_json_value(uri, value));
diff --git a/src/file/format/json5.rs b/src/file/format/json5.rs
index ea3390f..952b265 100644
--- a/src/file/format/json5.rs
+++ b/src/file/format/json5.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use crate::error::{ConfigError, Unexpected};
@@ -13,13 +13,13 @@ pub enum Val {
Float(f64),
String(String),
Array(Vec<Val>),
- Object(HashMap<String, Val>),
+ Object(LinkedHashMap<String, Val>),
}
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<LinkedHashMap<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::Integer(value)),
@@ -29,7 +29,7 @@ pub fn parse(
Val::Null => Err(Unexpected::Unit),
Val::Object(o) => match from_json5_value(uri, Val::Object(o)).kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(HashMap::new()),
+ _ => Ok(LinkedHashMap::new()),
},
}
.map_err(|err| ConfigError::invalid_root(uri, err))
diff --git a/src/file/format/mod.rs b/src/file/format/mod.rs
index 53bacf6..55d1c7a 100644
--- a/src/file/format/mod.rs
+++ b/src/file/format/mod.rs
@@ -2,7 +2,7 @@
// BUG: ? For some reason this doesn't do anything if I try and function scope this
#![allow(unused_mut)]
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use crate::value::Value;
@@ -62,8 +62,8 @@ pub enum FileFormat {
lazy_static! {
#[doc(hidden)]
// #[allow(unused_mut)] ?
- pub static ref ALL_EXTENSIONS: HashMap<FileFormat, Vec<&'static str>> = {
- let mut formats: HashMap<FileFormat, Vec<_>> = HashMap::new();
+ pub static ref ALL_EXTENSIONS: LinkedHashMap<FileFormat, Vec<&'static str>> = {
+ let mut formats: LinkedHashMap<FileFormat, Vec<_>> = LinkedHashMap::new();
#[cfg(feature = "toml")]
formats.insert(FileFormat::Toml, vec!["toml"]);
@@ -107,7 +107,7 @@ impl FileFormat {
self,
uri: Option<&String>,
text: &str,
- ) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+ ) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
match self {
#[cfg(feature = "toml")]
FileFormat::Toml => toml::parse(uri, text),
diff --git a/src/file/format/ron.rs b/src/file/format/ron.rs
index f7dbce3..a527d6f 100644
--- a/src/file/format/ron.rs
+++ b/src/file/format/ron.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use crate::value::{Value, ValueKind};
@@ -6,12 +6,12 @@ use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<LinkedHashMap<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(HashMap::new()),
+ _ => Ok(LinkedHashMap::new()),
}
}
@@ -56,7 +56,7 @@ fn from_ron_value(
Ok((key, value))
})
- .collect::<Result<HashMap<_, _>, _>>()?;
+ .collect::<Result<LinkedHashMap<_, _>, _>>()?;
ValueKind::Table(map)
}
diff --git a/src/file/format/toml.rs b/src/file/format/toml.rs
index c7c5972..5468d97 100644
--- a/src/file/format/toml.rs
+++ b/src/file/format/toml.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use crate::value::{Value, ValueKind};
@@ -6,14 +6,14 @@ use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<LinkedHashMap<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(HashMap::new()),
+ _ => Ok(LinkedHashMap::new()),
}
}
@@ -25,7 +25,7 @@ fn from_toml_value(uri: Option<&String>, value: &toml::Value) -> Value {
toml::Value::Boolean(value) => Value::new(uri, value),
toml::Value::Table(ref table) => {
- let mut m = HashMap::new();
+ let mut m = LinkedHashMap::new();
for (key, value) in table {
m.insert(key.clone(), from_toml_value(uri, value));
diff --git a/src/file/format/yaml.rs b/src/file/format/yaml.rs
index 2526395..246758a 100644
--- a/src/file/format/yaml.rs
+++ b/src/file/format/yaml.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::error::Error;
use std::fmt;
use std::mem;
@@ -10,7 +10,7 @@ use crate::value::{Value, ValueKind};
pub fn parse(
uri: Option<&String>,
text: &str,
-) -> Result<HashMap<String, Value>, Box<dyn Error + Send + Sync>> {
+) -> Result<LinkedHashMap<String, Value>, Box<dyn Error + Send + Sync>> {
// Parse a YAML object from file
let mut docs = yaml::YamlLoader::load_from_str(text)?;
let root = match docs.len() {
@@ -26,7 +26,7 @@ pub fn parse(
match value.kind {
ValueKind::Table(map) => Ok(map),
- _ => Ok(HashMap::new()),
+ _ => Ok(LinkedHashMap::new()),
}
}
@@ -40,7 +40,7 @@ fn from_yaml_value(uri: Option<&String>, value: &yaml::Yaml) -> Value {
yaml::Yaml::Integer(value) => Value::new(uri, ValueKind::Integer(value)),
yaml::Yaml::Boolean(value) => Value::new(uri, ValueKind::Boolean(value)),
yaml::Yaml::Hash(ref table) => {
- let mut m = HashMap::new();
+ let mut m = LinkedHashMap::new();
for (key, value) in table {
if let Some(k) = key.as_str() {
m.insert(k.to_owned(), from_yaml_value(uri, value));
diff --git a/src/file/mod.rs b/src/file/mod.rs
index b00a271..02fd51f 100644
--- a/src/file/mod.rs
+++ b/src/file/mod.rs
@@ -1,7 +1,7 @@
mod format;
pub mod source;
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::path::{Path, PathBuf};
use crate::error::*;
@@ -99,7 +99,7 @@ where
Box::new((*self).clone())
}
- fn collect(&self) -> Result<HashMap<String, Value>> {
+ fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
// Coerce the file contents to a string
let (uri, contents, format) = match self
.source
@@ -110,7 +110,7 @@ where
Err(error) => {
if !self.required {
- return Ok(HashMap::new());
+ return Ok(LinkedHashMap::new());
}
return Err(error);
diff --git a/src/path/mod.rs b/src/path/mod.rs
index d58a6f2..04c424c 100644
--- a/src/path/mod.rs
+++ b/src/path/mod.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::str::FromStr;
use crate::error::*;
@@ -135,7 +135,7 @@ impl Expression {
),
_ => {
- *value = HashMap::<String, Value>::new().into();
+ *value = LinkedHashMap::<String, Value>::new().into();
if let ValueKind::Table(ref mut map) = value.kind {
Some(
@@ -186,7 +186,7 @@ impl Expression {
ValueKind::Table(_) => {}
_ => {
- *root = HashMap::<String, Value>::new().into();
+ *root = LinkedHashMap::<String, Value>::new().into();
}
}
@@ -195,7 +195,7 @@ impl Expression {
// Pull out another table
let mut target = if let ValueKind::Table(ref mut map) = root.kind {
map.entry(id.clone())
- .or_insert_with(|| HashMap::<String, Value>::new().into())
+ .or_insert_with(|| LinkedHashMap::<String, Value>::new().into())
} else {
unreachable!();
};
@@ -224,7 +224,7 @@ impl Expression {
_ => {
// Didn't find a table. Oh well. Make a table and do this anyway
- *parent = HashMap::<String, Value>::new().into();
+ *parent = LinkedHashMap::<String, Value>::new().into();
Expression::Identifier(key.clone()).set(parent, value);
}
diff --git a/src/source.rs b/src/source.rs
index 831e4c4..7d257d0 100644
--- a/src/source.rs
+++ b/src/source.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::fmt::Debug;
use std::str::FromStr;
@@ -13,8 +13,8 @@ pub trait Source: Debug {
fn clone_into_box(&self) -> Box<dyn Source + Send + Sync>;
/// Collect all configuration properties available from this source and return
- /// a HashMap.
- fn collect(&self) -> Result<HashMap<String, Value>>;
+ /// a LinkedHashMap.
+ fn collect(&self) -> Result<LinkedHashMap<String, Value>>;
/// Collects all configuration properties to a provided cache.
fn collect_to(&self, cache: &mut Value) -> Result<()> {
@@ -55,8 +55,8 @@ pub trait AsyncSource: Debug + Sync {
// Sync is supertrait due to https://docs.rs/async-trait/0.1.50/async_trait/index.html#dyn-traits
/// Collects all configuration properties available from this source and return
- /// a HashMap as an async operations.
- async fn collect(&self) -> Result<HashMap<String, Value>>;
+ /// a LinkedHashMap as an async operations.
+ async fn collect(&self) -> Result<LinkedHashMap<String, Value>>;
/// Collects all configuration properties to a provided cache.
async fn collect_to(&self, cache: &mut Value) -> Result<()> {
@@ -86,8 +86,8 @@ impl Source for Vec<Box<dyn Source + Send + Sync>> {
Box::new((*self).clone())
}
- fn collect(&self) -> Result<HashMap<String, Value>> {
- let mut cache: Value = HashMap::<String, Value>::new().into();
+ fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
+ let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
for source in self {
source.collect_to(&mut cache)?;
@@ -106,8 +106,8 @@ impl Source for [Box<dyn Source + Send + Sync>] {
Box::new(self.to_owned())
}
- fn collect(&self) -> Result<HashMap<String, Value>> {
- let mut cache: Value = HashMap::<String, Value>::new().into();
+ fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
+ let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
for source in self {
source.collect_to(&mut cache)?;
@@ -131,8 +131,8 @@ where
Box::new((*self).clone())
}
- fn collect(&self) -> Result<HashMap<String, Value>> {
- let mut cache: Value = HashMap::<String, Value>::new().into();
+ fn collect(&self) -> Result<LinkedHashMap<String, Value>> {
+ let mut cache: Value = LinkedHashMap::<String, Value>::new().into();
for source in self {
source.collect_to(&mut cache)?;
diff --git a/src/value.rs b/src/value.rs
index 8db5fcc..e8f41c9 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use linked_hash_map::LinkedHashMap;
use std::fmt;
use std::fmt::Display;
@@ -23,7 +23,7 @@ pub enum ValueKind {
}
pub type Array = Vec<Value>;
-pub type Table = HashMap<String, Value>;
+pub type Table = LinkedHashMap<String, Value>;
impl Default for ValueKind {
fn default() -> Self {
@@ -73,11 +73,11 @@ impl From<bool> for ValueKind {
}
}
-impl<T> From<HashMap<String, T>> for ValueKind
+impl<T> From<LinkedHashMap<String, T>> for ValueKind
where
T: Into<Value>,
{
- fn from(values: HashMap<String, T>) -> Self {
+ fn from(values: LinkedHashMap<String, T>) -> Self {
let t = values.into_iter().map(|(k, v)| (k, v.into())).collect();
ValueKind::Table(t)
}
@@ -357,7 +357,7 @@ impl Value {
/// If the `Value` is a Table, returns the associated Map.
// FIXME: Should this not be `try_into_*` ?
- pub fn into_table(self) -> Result<HashMap<String, Value>> {
+ pub fn into_table(self) -> Result<LinkedHashMap<String, Value>> {
match self.kind {
ValueKind::Table(value) => Ok(value),