mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-23 18:29:50 -04:00
REFACTOR: No longer require PositionedItem for Val::Tuples.
This commit is contained in:
parent
535d201edc
commit
ceaed5c543
@ -18,7 +18,8 @@ pub enum Val {
|
|||||||
Float(f64),
|
Float(f64),
|
||||||
Str(String),
|
Str(String),
|
||||||
List(Vec<Rc<Val>>),
|
List(Vec<Rc<Val>>),
|
||||||
Tuple(Vec<(PositionedItem<String>, Rc<Val>)>),
|
// TODO(jwall): Remove the need for PositionedItem here
|
||||||
|
Tuple(Vec<(String, Rc<Val>)>),
|
||||||
Env(Vec<(String, String)>),
|
Env(Vec<(String, String)>),
|
||||||
Func(FuncDef),
|
Func(FuncDef),
|
||||||
Module(ModuleDef),
|
Module(ModuleDef),
|
||||||
@ -86,12 +87,12 @@ impl Val {
|
|||||||
} else {
|
} else {
|
||||||
for (i, lv) in ldef.iter().enumerate() {
|
for (i, lv) in ldef.iter().enumerate() {
|
||||||
let field_target = &rdef[i];
|
let field_target = &rdef[i];
|
||||||
if lv.0.val != field_target.0.val {
|
if lv.0 != field_target.0 {
|
||||||
// field name equality
|
// field name equality
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
} else {
|
} else {
|
||||||
// field value equality.
|
// field value equality.
|
||||||
if !lv.1.equal(field_target.1.as_ref(), lv.0.pos.clone())? {
|
if !lv.1.equal(field_target.1.as_ref(), pos.clone())? {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,6 +100,7 @@ impl Val {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// FIXME(jwall): Maybe we don't require positions here?
|
||||||
(&Val::Func(_), &Val::Func(_)) => Err(error::BuildError::new(
|
(&Val::Func(_), &Val::Func(_)) => Err(error::BuildError::new(
|
||||||
"Func are not comparable",
|
"Func are not comparable",
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
@ -121,7 +123,7 @@ impl Val {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the fields if this Val is a tuple. None otherwise.
|
/// Returns the fields if this Val is a tuple. None otherwise.
|
||||||
pub fn get_fields(&self) -> Option<&Vec<(PositionedItem<String>, Rc<Val>)>> {
|
pub fn get_fields(&self) -> Option<&Vec<(String, Rc<Val>)>> {
|
||||||
if let &Val::Tuple(ref fs) = self {
|
if let &Val::Tuple(ref fs) = self {
|
||||||
Some(fs)
|
Some(fs)
|
||||||
} else {
|
} else {
|
||||||
@ -227,7 +229,7 @@ impl Display for Val {
|
|||||||
&Val::Tuple(ref def) => {
|
&Val::Tuple(ref def) => {
|
||||||
write!(f, "{{\n")?;
|
write!(f, "{{\n")?;
|
||||||
for v in def.iter() {
|
for v in def.iter() {
|
||||||
write!(f, "\t{} = {},\n", v.0.val, v.1)?;
|
write!(f, "\t{} = {},\n", v.0, v.1)?;
|
||||||
}
|
}
|
||||||
write!(f, "}}")
|
write!(f, "}}")
|
||||||
}
|
}
|
||||||
|
@ -254,10 +254,10 @@ impl<'a> FileBuilder<'a> {
|
|||||||
fields: &Vec<(Token, Expression)>,
|
fields: &Vec<(Token, Expression)>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
let mut new_fields = Vec::<(PositionedItem<String>, Rc<Val>)>::new();
|
let mut new_fields = Vec::<(String, Rc<Val>)>::new();
|
||||||
for &(ref name, ref expr) in fields.iter() {
|
for &(ref name, ref expr) in fields.iter() {
|
||||||
let val = self.eval_expr(expr, scope)?;
|
let val = self.eval_expr(expr, scope)?;
|
||||||
new_fields.push((name.into(), val));
|
new_fields.push((name.fragment.clone(), val));
|
||||||
}
|
}
|
||||||
Ok(Rc::new(Val::Tuple(new_fields)))
|
Ok(Rc::new(Val::Tuple(new_fields)))
|
||||||
}
|
}
|
||||||
@ -1014,18 +1014,22 @@ impl<'a> FileBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_outputs_as_val(&mut self) -> Rc<Val> {
|
fn get_outputs_as_val(&mut self) -> Rc<Val> {
|
||||||
let fields: Vec<(PositionedItem<String>, Rc<Val>)> =
|
let fields: Vec<(String, Rc<Val>)> = self
|
||||||
self.scope.build_output.drain().collect();
|
.scope
|
||||||
|
.build_output
|
||||||
|
.drain()
|
||||||
|
.map(|v| (v.0.val, v.1))
|
||||||
|
.collect();
|
||||||
Rc::new(Val::Tuple(fields))
|
Rc::new(Val::Tuple(fields))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_from_base(
|
fn copy_from_base(
|
||||||
&self,
|
&self,
|
||||||
src_fields: &Vec<(PositionedItem<String>, Rc<Val>)>,
|
src_fields: &Vec<(String, Rc<Val>)>,
|
||||||
overrides: &Vec<(Token, Expression)>,
|
overrides: &Vec<(Token, Expression)>,
|
||||||
scope: &Scope,
|
scope: &Scope,
|
||||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
let mut m = HashMap::<PositionedItem<String>, (i32, Rc<Val>)>::new();
|
let mut m = HashMap::<String, (i32, Rc<Val>)>::new();
|
||||||
// loop through fields and build up a hashmap
|
// loop through fields and build up a hashmap
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for &(ref key, ref val) in src_fields.iter() {
|
for &(ref key, ref val) in src_fields.iter() {
|
||||||
@ -1038,16 +1042,16 @@ impl<'a> FileBuilder<'a> {
|
|||||||
"Duplicate \
|
"Duplicate \
|
||||||
field: {} in \
|
field: {} in \
|
||||||
tuple",
|
tuple",
|
||||||
key.val
|
key
|
||||||
),
|
),
|
||||||
error::ErrorType::TypeFail,
|
error::ErrorType::TypeFail,
|
||||||
key.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for &(ref key, ref val) in overrides.iter() {
|
for &(ref key, ref val) in overrides.iter() {
|
||||||
let expr_result = self.eval_expr(val, scope)?;
|
let expr_result = self.eval_expr(val, scope)?;
|
||||||
match m.entry(key.into()) {
|
match m.entry(key.fragment.clone()) {
|
||||||
// brand new field here.
|
// brand new field here.
|
||||||
Entry::Vacant(v) => {
|
Entry::Vacant(v) => {
|
||||||
v.insert((count, expr_result));
|
v.insert((count, expr_result));
|
||||||
@ -1077,7 +1081,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let mut new_fields: Vec<(PositionedItem<String>, (i32, Rc<Val>))> = m.drain().collect();
|
let mut new_fields: Vec<(String, (i32, Rc<Val>))> = m.drain().collect();
|
||||||
// We want to maintain our order for the fields to make comparing tuples
|
// We want to maintain our order for the fields to make comparing tuples
|
||||||
// easier in later code. So we sort by the field order before constructing a new tuple.
|
// easier in later code. So we sort by the field order before constructing a new tuple.
|
||||||
new_fields.sort_by(|a, b| {
|
new_fields.sort_by(|a, b| {
|
||||||
@ -1312,13 +1316,13 @@ impl<'a> FileBuilder<'a> {
|
|||||||
|
|
||||||
fn eval_functional_tuple_processing(
|
fn eval_functional_tuple_processing(
|
||||||
&self,
|
&self,
|
||||||
fs: &Vec<(PositionedItem<String>, Rc<Val>)>,
|
fs: &Vec<(String, Rc<Val>)>,
|
||||||
def: &FuncDef,
|
def: &FuncDef,
|
||||||
typ: ProcessingOpType,
|
typ: ProcessingOpType,
|
||||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
for &(ref name, ref val) in fs {
|
for &(ref name, ref val) in fs {
|
||||||
let argvals = vec![Rc::new(Val::Str(name.val.clone())), val.clone()];
|
let argvals = vec![Rc::new(Val::Str(name.clone())), val.clone()];
|
||||||
let result = def.eval(self, argvals)?;
|
let result = def.eval(self, argvals)?;
|
||||||
match typ {
|
match typ {
|
||||||
ProcessingOpType::Map => {
|
ProcessingOpType::Map => {
|
||||||
@ -1338,10 +1342,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
def.pos.clone(),
|
def.pos.clone(),
|
||||||
)));
|
)));
|
||||||
};
|
};
|
||||||
out.push((
|
out.push((new_name, fs[1].clone()));
|
||||||
PositionedItem::new(new_name, name.pos.clone()),
|
|
||||||
fs[1].clone(),
|
|
||||||
));
|
|
||||||
} else {
|
} else {
|
||||||
return Err(Box::new(error::BuildError::new(
|
return Err(Box::new(error::BuildError::new(
|
||||||
format!(
|
format!(
|
||||||
@ -1402,11 +1403,7 @@ impl<'a> FileBuilder<'a> {
|
|||||||
}
|
}
|
||||||
&Val::Tuple(ref fs) => {
|
&Val::Tuple(ref fs) => {
|
||||||
for &(ref name, ref val) in fs.iter() {
|
for &(ref name, ref val) in fs.iter() {
|
||||||
let argvals = vec![
|
let argvals = vec![acc.clone(), Rc::new(Val::Str(name.clone())), val.clone()];
|
||||||
acc.clone(),
|
|
||||||
Rc::new(Val::Str(name.val.clone())),
|
|
||||||
val.clone(),
|
|
||||||
];
|
|
||||||
let result = funcdef.eval(self, argvals)?;
|
let result = funcdef.eval(self, argvals)?;
|
||||||
acc = result;
|
acc = result;
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,9 @@ use crate::ast::PositionedItem;
|
|||||||
use crate::build::ir::Val;
|
use crate::build::ir::Val;
|
||||||
use crate::error;
|
use crate::error;
|
||||||
|
|
||||||
pub fn find_in_fieldlist(
|
pub fn find_in_fieldlist(target: &str, fs: &Vec<(String, Rc<Val>)>) -> Option<Rc<Val>> {
|
||||||
target: &str,
|
|
||||||
fs: &Vec<(PositionedItem<String>, Rc<Val>)>,
|
|
||||||
) -> Option<Rc<Val>> {
|
|
||||||
for (key, val) in fs.iter().cloned() {
|
for (key, val) in fs.iter().cloned() {
|
||||||
if target == &key.val {
|
if target == &key {
|
||||||
return Some(val.clone());
|
return Some(val.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,7 +184,7 @@ impl Scope {
|
|||||||
fn lookup_in_tuple(
|
fn lookup_in_tuple(
|
||||||
pos: &Position,
|
pos: &Position,
|
||||||
field: &str,
|
field: &str,
|
||||||
fs: &Vec<(PositionedItem<String>, Rc<Val>)>,
|
fs: &Vec<(String, Rc<Val>)>,
|
||||||
) -> Result<Rc<Val>, Box<dyn Error>> {
|
) -> Result<Rc<Val>, Box<dyn Error>> {
|
||||||
if let Some(vv) = find_in_fieldlist(&field, fs) {
|
if let Some(vv) = find_in_fieldlist(&field, fs) {
|
||||||
Ok(vv)
|
Ok(vv)
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::ast::PositionedItem;
|
|
||||||
use crate::build::Val;
|
use crate::build::Val;
|
||||||
use crate::convert::traits::{ConvertResult, Converter};
|
use crate::convert::traits::{ConvertResult, Converter};
|
||||||
|
|
||||||
@ -29,11 +28,7 @@ impl EnvConverter {
|
|||||||
EnvConverter {}
|
EnvConverter {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(
|
fn convert_tuple(&self, flds: &Vec<(String, Rc<Val>)>, w: &mut Write) -> ConvertResult {
|
||||||
&self,
|
|
||||||
flds: &Vec<(PositionedItem<String>, Rc<Val>)>,
|
|
||||||
w: &mut Write,
|
|
||||||
) -> ConvertResult {
|
|
||||||
for &(ref name, ref val) in flds.iter() {
|
for &(ref name, ref val) in flds.iter() {
|
||||||
if val.is_tuple() {
|
if val.is_tuple() {
|
||||||
eprintln!("Skipping embedded tuple...");
|
eprintln!("Skipping embedded tuple...");
|
||||||
@ -43,7 +38,7 @@ impl EnvConverter {
|
|||||||
eprintln!("Skipping empty variable: {}", name);
|
eprintln!("Skipping empty variable: {}", name);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
write!(w, "{}=", name.val)?;
|
write!(w, "{}=", name)?;
|
||||||
self.write(&val, w)?;
|
self.write(&val, w)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -17,7 +17,7 @@ use std;
|
|||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::ast::{Position, PositionedItem};
|
use crate::ast::Position;
|
||||||
use crate::build::Val;
|
use crate::build::Val;
|
||||||
use crate::build::Val::Tuple;
|
use crate::build::Val::Tuple;
|
||||||
use crate::convert;
|
use crate::convert;
|
||||||
@ -49,17 +49,18 @@ impl ExecConverter {
|
|||||||
Position::new(0, 0, 0),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
let mut env: Option<&Vec<(PositionedItem<String>, Rc<Val>)>> = None;
|
let mut env: Option<&Vec<(String, Rc<Val>)>> = None;
|
||||||
let mut command: Option<&str> = None;
|
let mut command: Option<&str> = None;
|
||||||
let mut args: Option<&Vec<Rc<Val>>> = None;
|
let mut args: Option<&Vec<Rc<Val>>> = None;
|
||||||
for &(ref name, ref val) in fields.iter() {
|
for &(ref name, ref val) in fields.iter() {
|
||||||
|
// FIXME(jwall): BuildError should not require a Position.
|
||||||
// We require a command field in our exec tuple.
|
// We require a command field in our exec tuple.
|
||||||
if name.val == "command" {
|
if name == "command" {
|
||||||
if command.is_some() {
|
if command.is_some() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(Box::new(BuildError::new(
|
||||||
"There can only be one command field in an exec tuple",
|
"There can only be one command field in an exec tuple",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
name.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if let &Val::Str(ref s) = val.as_ref() {
|
if let &Val::Str(ref s) = val.as_ref() {
|
||||||
@ -69,17 +70,17 @@ impl ExecConverter {
|
|||||||
return Err(Box::new(BuildError::new(
|
return Err(Box::new(BuildError::new(
|
||||||
"The command field of an exec tuple must be a string",
|
"The command field of an exec tuple must be a string",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
name.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
// We optionally allow an env field in our exec tuple.
|
// We optionally allow an env field in our exec tuple.
|
||||||
if name.val == "env" {
|
if name == "env" {
|
||||||
if let &Val::Tuple(ref l) = val.as_ref() {
|
if let &Val::Tuple(ref l) = val.as_ref() {
|
||||||
if env.is_some() {
|
if env.is_some() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(Box::new(BuildError::new(
|
||||||
"There can only be one env field in an exec tuple",
|
"There can only be one env field in an exec tuple",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
name.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
env = Some(l);
|
env = Some(l);
|
||||||
@ -88,17 +89,17 @@ impl ExecConverter {
|
|||||||
return Err(Box::new(BuildError::new(
|
return Err(Box::new(BuildError::new(
|
||||||
"The env field of an exec tuple must be a list",
|
"The env field of an exec tuple must be a list",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
name.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
// We optionally allow an args field in our exec tuple.
|
// We optionally allow an args field in our exec tuple.
|
||||||
if name.val == "args" {
|
if name == "args" {
|
||||||
if let &Val::List(ref l) = val.as_ref() {
|
if let &Val::List(ref l) = val.as_ref() {
|
||||||
if args.is_some() {
|
if args.is_some() {
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(Box::new(BuildError::new(
|
||||||
"There can only be one args field of an exec tuple",
|
"There can only be one args field of an exec tuple",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
name.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
args = Some(l);
|
args = Some(l);
|
||||||
@ -107,7 +108,7 @@ impl ExecConverter {
|
|||||||
return Err(Box::new(BuildError::new(
|
return Err(Box::new(BuildError::new(
|
||||||
"The args field of an exec tuple must be a list",
|
"The args field of an exec tuple must be a list",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
name.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,13 +131,13 @@ impl ExecConverter {
|
|||||||
for &(ref name, ref v) in env_list.iter() {
|
for &(ref name, ref v) in env_list.iter() {
|
||||||
// We only allow string fields in our env tuple.
|
// We only allow string fields in our env tuple.
|
||||||
if let &Val::Str(ref s) = v.as_ref() {
|
if let &Val::Str(ref s) = v.as_ref() {
|
||||||
write!(script, "{}=\"{}\"\n", name.val, s)?;
|
write!(script, "{}=\"{}\"\n", name, s)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return Err(Box::new(BuildError::new(
|
return Err(Box::new(BuildError::new(
|
||||||
"The env fields of an exec tuple must contain only string values",
|
"The env fields of an exec tuple must contain only string values",
|
||||||
ErrorType::TypeFail,
|
ErrorType::TypeFail,
|
||||||
name.pos.clone(),
|
Position::new(0, 0, 0),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ impl FlagConverter {
|
|||||||
&Val::Tuple(ref flds) => {
|
&Val::Tuple(ref flds) => {
|
||||||
for &(ref name, ref val) in flds.iter() {
|
for &(ref name, ref val) in flds.iter() {
|
||||||
if let &Val::Empty = val.as_ref() {
|
if let &Val::Empty = val.as_ref() {
|
||||||
self.write_flag_name(pfx, &name.val, w)?;
|
self.write_flag_name(pfx, name, w)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match val.as_ref() {
|
match val.as_ref() {
|
||||||
@ -93,10 +93,10 @@ impl FlagConverter {
|
|||||||
self.write(&new_pfx, val, w)?;
|
self.write(&new_pfx, val, w)?;
|
||||||
}
|
}
|
||||||
&Val::List(ref def) => {
|
&Val::List(ref def) => {
|
||||||
self.write_list_flag(pfx, &name.val, def, w)?;
|
self.write_list_flag(pfx, name, def, w)?;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.write_flag_name(pfx, &name.val, w)?;
|
self.write_flag_name(pfx, name, w)?;
|
||||||
self.write(pfx, &val, w)?;
|
self.write(pfx, &val, w)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
use crate::ast;
|
|
||||||
use crate::build::Val;
|
use crate::build::Val;
|
||||||
use crate::convert::traits::{ConvertResult, Converter, ImportResult, Importer};
|
use crate::convert::traits::{ConvertResult, Converter, ImportResult, Importer};
|
||||||
|
|
||||||
@ -35,13 +34,10 @@ impl JsonConverter {
|
|||||||
Ok(serde_json::Value::Array(v))
|
Ok(serde_json::Value::Array(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(
|
fn convert_tuple(&self, items: &Vec<(String, Rc<Val>)>) -> std::io::Result<serde_json::Value> {
|
||||||
&self,
|
|
||||||
items: &Vec<(ast::PositionedItem<String>, Rc<Val>)>,
|
|
||||||
) -> std::io::Result<serde_json::Value> {
|
|
||||||
let mut mp = serde_json::Map::new();
|
let mut mp = serde_json::Map::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mp.entry(k.val.clone()).or_insert(self.convert_value(v)?);
|
mp.entry(k.clone()).or_insert(self.convert_value(v)?);
|
||||||
}
|
}
|
||||||
Ok(serde_json::Value::Object(mp))
|
Ok(serde_json::Value::Object(mp))
|
||||||
}
|
}
|
||||||
@ -113,10 +109,7 @@ impl JsonConverter {
|
|||||||
serde_json::Value::Object(m) => {
|
serde_json::Value::Object(m) => {
|
||||||
let mut fs = Vec::with_capacity(m.len());
|
let mut fs = Vec::with_capacity(m.len());
|
||||||
for (key, value) in m {
|
for (key, value) in m {
|
||||||
fs.push((
|
fs.push((key.to_string(), Rc::new(self.convert_json_val(value)?)));
|
||||||
ast::PositionedItem::new(key.to_string(), ast::Position::new(0, 0, 0)),
|
|
||||||
Rc::new(self.convert_json_val(value)?),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
Val::Tuple(fs)
|
Val::Tuple(fs)
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ use std::rc::Rc;
|
|||||||
use simple_error::SimpleError;
|
use simple_error::SimpleError;
|
||||||
use toml;
|
use toml;
|
||||||
|
|
||||||
use crate::ast;
|
|
||||||
use crate::build::Val;
|
use crate::build::Val;
|
||||||
use crate::convert::traits::{ConvertResult, Converter};
|
use crate::convert::traits::{ConvertResult, Converter};
|
||||||
|
|
||||||
@ -41,10 +40,10 @@ impl TomlConverter {
|
|||||||
Ok(toml::Value::Array(v))
|
Ok(toml::Value::Array(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(&self, items: &Vec<(ast::PositionedItem<String>, Rc<Val>)>) -> Result {
|
fn convert_tuple(&self, items: &Vec<(String, Rc<Val>)>) -> Result {
|
||||||
let mut mp = toml::value::Table::new();
|
let mut mp = toml::value::Table::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mp.entry(k.val.clone()).or_insert(self.convert_value(v)?);
|
mp.entry(k.clone()).or_insert(self.convert_value(v)?);
|
||||||
}
|
}
|
||||||
Ok(toml::Value::Table(mp))
|
Ok(toml::Value::Table(mp))
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ use std::io::Write;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::traits::{ConvertResult, Converter};
|
use super::traits::{ConvertResult, Converter};
|
||||||
use crate::ast::{Position, PositionedItem};
|
use crate::ast::Position;
|
||||||
use crate::build::Val;
|
use crate::build::Val;
|
||||||
use crate::error::BuildError;
|
use crate::error::BuildError;
|
||||||
use crate::error::ErrorType;
|
use crate::error::ErrorType;
|
||||||
@ -43,9 +43,7 @@ impl XmlConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_tuple_val(
|
fn get_tuple_val(v: &Val) -> std::result::Result<&Vec<(String, Rc<Val>)>, Box<dyn Error>> {
|
||||||
v: &Val,
|
|
||||||
) -> std::result::Result<&Vec<(PositionedItem<String>, Rc<Val>)>, Box<dyn Error>> {
|
|
||||||
if let Val::Tuple(ref fs) = v {
|
if let Val::Tuple(ref fs) = v {
|
||||||
Ok(fs)
|
Ok(fs)
|
||||||
} else {
|
} else {
|
||||||
@ -73,15 +71,15 @@ impl XmlConverter {
|
|||||||
// First we determine if this is a tag or text node
|
// First we determine if this is a tag or text node
|
||||||
if let Val::Tuple(ref fs) = v {
|
if let Val::Tuple(ref fs) = v {
|
||||||
let mut name: Option<&str> = None;
|
let mut name: Option<&str> = None;
|
||||||
let mut attrs: Option<&Vec<(PositionedItem<String>, Rc<Val>)>> = None;
|
let mut attrs: Option<&Vec<(String, Rc<Val>)>> = None;
|
||||||
let mut children: Option<&Vec<Rc<Val>>> = None;
|
let mut children: Option<&Vec<Rc<Val>>> = None;
|
||||||
let mut text: Option<&str> = None;
|
let mut text: Option<&str> = None;
|
||||||
let mut ns: Option<(&str, &str)> = None;
|
let mut ns: Option<(&str, &str)> = None;
|
||||||
for (ref field, ref val) in fs.iter() {
|
for (ref field, ref val) in fs.iter() {
|
||||||
if field.val == "name" {
|
if field == "name" {
|
||||||
name = Some(Self::get_str_val(val.as_ref())?);
|
name = Some(Self::get_str_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
if field.val == "ns" {
|
if field == "ns" {
|
||||||
if let Val::Tuple(ref fs) = val.as_ref() {
|
if let Val::Tuple(ref fs) = val.as_ref() {
|
||||||
let mut prefix = "";
|
let mut prefix = "";
|
||||||
let mut uri = "";
|
let mut uri = "";
|
||||||
@ -89,10 +87,10 @@ impl XmlConverter {
|
|||||||
if val.is_empty() {
|
if val.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if name.val == "uri" {
|
if name == "uri" {
|
||||||
uri = Self::get_str_val(val.as_ref())?;
|
uri = Self::get_str_val(val.as_ref())?;
|
||||||
}
|
}
|
||||||
if name.val == "prefix" {
|
if name == "prefix" {
|
||||||
prefix = Self::get_str_val(val.as_ref())?;
|
prefix = Self::get_str_val(val.as_ref())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,19 +101,19 @@ impl XmlConverter {
|
|||||||
ns = Some(("", s));
|
ns = Some(("", s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field.val == "attrs" {
|
if field == "attrs" {
|
||||||
// This should be a tuple.
|
// This should be a tuple.
|
||||||
if !val.is_empty() {
|
if !val.is_empty() {
|
||||||
attrs = Some(Self::get_tuple_val(val.as_ref())?);
|
attrs = Some(Self::get_tuple_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field.val == "children" {
|
if field == "children" {
|
||||||
// This should be a list of tuples.
|
// This should be a list of tuples.
|
||||||
if !val.is_empty() {
|
if !val.is_empty() {
|
||||||
children = Some(Self::get_list_val(val.as_ref())?);
|
children = Some(Self::get_list_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field.val == "text" {
|
if field == "text" {
|
||||||
if !val.is_empty() {
|
if !val.is_empty() {
|
||||||
text = Some(Self::get_str_val(val.as_ref())?);
|
text = Some(Self::get_str_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
@ -135,7 +133,7 @@ impl XmlConverter {
|
|||||||
if val.is_empty() {
|
if val.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
start = start.attr(name.val.as_ref(), Self::get_str_val(val.as_ref())?);
|
start = start.attr(name.as_ref(), Self::get_str_val(val.as_ref())?);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some((prefix, uri)) = ns {
|
if let Some((prefix, uri)) = ns {
|
||||||
@ -175,19 +173,19 @@ impl XmlConverter {
|
|||||||
let mut standalone: Option<bool> = None;
|
let mut standalone: Option<bool> = None;
|
||||||
let mut root: Option<Rc<Val>> = None;
|
let mut root: Option<Rc<Val>> = None;
|
||||||
for &(ref name, ref val) in fs.iter() {
|
for &(ref name, ref val) in fs.iter() {
|
||||||
if name.val == "version" {
|
if name == "version" {
|
||||||
version = Some(Self::get_str_val(val)?);
|
version = Some(Self::get_str_val(val)?);
|
||||||
}
|
}
|
||||||
if name.val == "encoding" {
|
if name == "encoding" {
|
||||||
encoding = Some(Self::get_str_val(val)?);
|
encoding = Some(Self::get_str_val(val)?);
|
||||||
}
|
}
|
||||||
if name.val == "standalone" {
|
if name == "standalone" {
|
||||||
standalone = match val.as_ref() {
|
standalone = match val.as_ref() {
|
||||||
Val::Boolean(b) => Some(*b),
|
Val::Boolean(b) => Some(*b),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if name.val == "root" {
|
if name == "root" {
|
||||||
root = Some(val.clone());
|
root = Some(val.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use std::result::Result;
|
|||||||
use serde_yaml;
|
use serde_yaml;
|
||||||
|
|
||||||
use super::traits::{ConvertResult, Converter, ImportResult, Importer};
|
use super::traits::{ConvertResult, Converter, ImportResult, Importer};
|
||||||
use crate::ast;
|
|
||||||
use crate::build::Val;
|
use crate::build::Val;
|
||||||
|
|
||||||
pub struct YamlConverter {}
|
pub struct YamlConverter {}
|
||||||
@ -36,16 +35,10 @@ impl YamlConverter {
|
|||||||
Ok(serde_yaml::Value::Mapping(mp))
|
Ok(serde_yaml::Value::Mapping(mp))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn convert_tuple(
|
fn convert_tuple(&self, items: &Vec<(String, Rc<Val>)>) -> std::io::Result<serde_yaml::Value> {
|
||||||
&self,
|
|
||||||
items: &Vec<(ast::PositionedItem<String>, Rc<Val>)>,
|
|
||||||
) -> std::io::Result<serde_yaml::Value> {
|
|
||||||
let mut mapping = serde_yaml::Mapping::new();
|
let mut mapping = serde_yaml::Mapping::new();
|
||||||
for &(ref k, ref v) in items.iter() {
|
for &(ref k, ref v) in items.iter() {
|
||||||
mapping.insert(
|
mapping.insert(serde_yaml::Value::String(k.clone()), self.convert_value(v)?);
|
||||||
serde_yaml::Value::String(k.val.clone()),
|
|
||||||
self.convert_value(v)?,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Ok(serde_yaml::Value::Mapping(mapping))
|
Ok(serde_yaml::Value::Mapping(mapping))
|
||||||
}
|
}
|
||||||
@ -113,10 +106,7 @@ impl YamlConverter {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("yaml key is: {}", key);
|
eprintln!("yaml key is: {}", key);
|
||||||
fs.push((
|
fs.push((key, Rc::new(self.convert_json_val(value)?)));
|
||||||
ast::PositionedItem::new(key, ast::Position::new(0, 0, 0)),
|
|
||||||
Rc::new(self.convert_json_val(value)?),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
Val::Tuple(fs)
|
Val::Tuple(fs)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user