2018-02-04 16:08:30 -06:00
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
2018-02-07 19:49:13 -06:00
|
|
|
//! Flags contains code for converting a UCG Val into the json output target.
|
2018-06-18 22:07:18 -05:00
|
|
|
use std;
|
2018-05-14 21:34:38 -05:00
|
|
|
use std::io::Write;
|
|
|
|
use std::rc::Rc;
|
2018-02-04 16:08:30 -06:00
|
|
|
|
|
|
|
use serde_json;
|
|
|
|
|
|
|
|
use ast;
|
|
|
|
use build::Val;
|
2018-06-18 22:07:18 -05:00
|
|
|
use convert::traits::{Converter, Result};
|
2018-02-04 16:08:30 -06:00
|
|
|
|
2018-02-07 19:49:13 -06:00
|
|
|
/// JsonConverter implements the logic for converting a Val into the json output format.
|
2018-02-04 16:08:30 -06:00
|
|
|
pub struct JsonConverter {}
|
|
|
|
|
|
|
|
impl JsonConverter {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
JsonConverter {}
|
|
|
|
}
|
|
|
|
|
2018-06-18 22:07:18 -05:00
|
|
|
fn convert_list(&self, items: &Vec<Rc<Val>>) -> std::io::Result<serde_json::Value> {
|
2018-02-04 16:08:30 -06:00
|
|
|
let mut v = Vec::new();
|
|
|
|
for val in items.iter() {
|
|
|
|
v.push(try!(self.convert_value(val)));
|
|
|
|
}
|
|
|
|
Ok(serde_json::Value::Array(v))
|
|
|
|
}
|
|
|
|
|
2018-02-15 19:55:43 -06:00
|
|
|
fn convert_tuple(
|
|
|
|
&self,
|
2018-05-22 18:02:44 -05:00
|
|
|
items: &Vec<(ast::Positioned<String>, Rc<Val>)>,
|
2018-06-18 22:07:18 -05:00
|
|
|
) -> std::io::Result<serde_json::Value> {
|
2018-02-04 16:08:30 -06:00
|
|
|
let mut mp = serde_json::Map::new();
|
|
|
|
for &(ref k, ref v) in items.iter() {
|
2018-02-15 19:55:43 -06:00
|
|
|
mp.entry(k.val.clone())
|
|
|
|
.or_insert(try!(self.convert_value(v)));
|
2018-02-04 16:08:30 -06:00
|
|
|
}
|
|
|
|
Ok(serde_json::Value::Object(mp))
|
|
|
|
}
|
|
|
|
|
2018-06-18 22:07:18 -05:00
|
|
|
fn convert_value(&self, v: &Val) -> std::io::Result<serde_json::Value> {
|
2018-02-04 16:08:30 -06:00
|
|
|
let jsn_val = match v {
|
2018-03-22 20:09:38 -05:00
|
|
|
&Val::Boolean(b) => serde_json::Value::Bool(b),
|
2018-03-12 20:29:31 -05:00
|
|
|
&Val::Empty => serde_json::Value::Null,
|
2018-02-04 16:08:30 -06:00
|
|
|
&Val::Float(f) => {
|
|
|
|
let n = match serde_json::Number::from_f64(f) {
|
|
|
|
Some(n) => n,
|
|
|
|
// In theory this should never happen. But on the off chance that it does...
|
|
|
|
None => panic!("Float is too large or Not a Number {}", f),
|
|
|
|
};
|
|
|
|
serde_json::Value::Number(n)
|
2018-02-05 19:41:47 -06:00
|
|
|
}
|
2018-02-04 16:08:30 -06:00
|
|
|
&Val::Int(i) => {
|
|
|
|
let n = match serde_json::Number::from_f64(i as f64) {
|
|
|
|
Some(n) => n,
|
|
|
|
// In theory this should never happen. But on the off chance that it does...
|
|
|
|
None => panic!("Float is too large or Not a Number {}", i),
|
|
|
|
};
|
|
|
|
serde_json::Value::Number(n)
|
2018-02-05 19:41:47 -06:00
|
|
|
}
|
2018-06-10 14:13:08 -05:00
|
|
|
&Val::Str(ref s) => serde_json::Value::String(s.clone()),
|
2018-02-04 16:08:30 -06:00
|
|
|
&Val::Macro(_) => {
|
|
|
|
eprintln!("Skipping macro encoding as null...");
|
|
|
|
serde_json::Value::Null
|
2018-02-05 19:41:47 -06:00
|
|
|
}
|
2018-02-04 16:08:30 -06:00
|
|
|
&Val::List(ref l) => try!(self.convert_list(l)),
|
|
|
|
&Val::Tuple(ref t) => try!(self.convert_tuple(t)),
|
|
|
|
};
|
|
|
|
Ok(jsn_val)
|
|
|
|
}
|
2018-02-05 19:41:47 -06:00
|
|
|
|
2018-06-18 22:07:18 -05:00
|
|
|
fn write(&self, v: &Val, w: &mut Write) -> Result {
|
2018-02-04 16:08:30 -06:00
|
|
|
let jsn_val = try!(self.convert_value(v));
|
|
|
|
try!(serde_json::to_writer(w, &jsn_val));
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Converter for JsonConverter {
|
2018-06-20 17:19:17 -04:00
|
|
|
fn convert(&self, v: Rc<Val>, mut w: &mut Write) -> Result {
|
2018-02-04 16:08:30 -06:00
|
|
|
self.write(&v, &mut w)
|
|
|
|
}
|
2018-08-15 18:22:05 -05:00
|
|
|
|
|
|
|
fn file_ext(&self) -> String {
|
|
|
|
String::from("json")
|
|
|
|
}
|
2018-02-05 19:41:47 -06:00
|
|
|
}
|