1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
pub mod ast;
pub mod fmt;
use axon_parseast_parser::parse as ap_parse;
use std::convert::TryInto;
use thiserror::Error;
/// If the axon input represents a function, return a `ast::Func`.
///
/// The `axon` argument to this function should be a string containing the
/// output of running `toAxonCode(parseAst( ... ))` in SkySpark.
///
/// # Example
/// ```rust
/// use axon_parser::parse_func;
///
/// let axon = r###"{type:"func", params:[], body:{type:"block", exprs:[{type:"literal", val:"hello world"}]}}"###;
/// let func = parse_func(axon).unwrap();
/// assert!(func.params.len() == 0)
/// ```
///
pub fn parse_func(axon: &str) -> Result<ast::Func, Error> {
let val = &ap_parse(axon).map_err(|_| Error::Parse)?;
let func: Result<ast::Func, ()> = val.try_into();
let func = func.map_err(|_| Error::AstConversion)?;
Ok(func)
}
/// If the axon input represents a comp, return a `ast::Comp`.
///
/// The `axon` argument to this function should be a string containing the
/// output of running `toAxonCode(parseAst( ... ))` in SkySpark.
///
/// # Example
/// ```rust
/// use axon_parser::parse_comp;
/// use raystack_core::TagName;
///
/// let axon = r###"{type:"compdef", params:[{name:"cells"}], body:{type:"block", exprs:[{type:"var", name:"in"}]}, cells:{in:{defVal:0}}}"###;
/// let comp = parse_comp(axon).unwrap();
/// let key = TagName::new("in".to_owned()).unwrap();
/// assert!(comp.cells.contains_key(&key))
/// ```
///
pub fn parse_comp(axon: &str) -> Result<ast::Comp, Error> {
let val = &ap_parse(axon).map_err(|_| Error::Parse)?;
let comp: Result<ast::Comp, ()> = val.try_into();
let comp = comp.map_err(|_| Error::AstConversion)?;
Ok(comp)
}
/// Encapsulates the types of errors that can occur in this library.
#[derive(Debug, Error)]
pub enum Error {
#[error("Could not parse the representation of Axon code")]
Parse,
#[error(
"Could not parse the loosely-typed Axon Val into a strongly-typed AST"
)]
AstConversion,
#[error("Could not rewrite the AST")]
Rewrite,
}
/// If the axon input represents a function or comp, parse it and return a `String`
/// which contains formatted code.
///
/// The `axon` argument to this function should be a string containing the
/// output of running `<some code>.parseAst.toAxonCode` in SkySpark.
///
/// # Example
/// ```rust
/// use axon_parser::format;
///
/// let desired_width = 80;
/// let axon = r###"{type:"func", params:[], body:{type:"block", exprs:[{type:"literal", val:"hello world"}]}}"###;
/// let formatted_code = format(axon, desired_width).unwrap();
/// let expected_code = "() => do\n \"hello world\"\nend";
/// assert_eq!(formatted_code, expected_code);
/// ```
///
pub fn format(axon: &str, desired_width: usize) -> Result<String, Error> {
let func = parse_func(axon);
if func.is_ok() {
return format_func(axon, desired_width);
}
let comp = parse_comp(axon);
if comp.is_ok() {
return format_comp(axon, desired_width);
}
Err(Error::Parse)
}
/// If the axon input represents a function, parse it and return a `String`
/// which contains formatted code.
///
/// The `axon` argument to this function should be a string containing the
/// output of running `<some function src>.parseAst.toAxonCode` in SkySpark.
///
/// # Example
/// ```rust
/// use axon_parser::format_func;
///
/// let desired_width = 80;
/// let axon = r###"{type:"func", params:[], body:{type:"block", exprs:[{type:"literal", val:"hello world"}]}}"###;
/// let formatted_code = format_func(axon, desired_width).unwrap();
/// let expected_code = "() => do\n \"hello world\"\nend";
/// assert_eq!(formatted_code, expected_code);
/// ```
///
pub fn format_func(axon: &str, desired_width: usize) -> Result<String, Error> {
let func = parse_func(axon)?;
let context = fmt::Context::new(0, desired_width);
let widen = true;
let code = func.default_rewrite(context, widen);
code.ok_or(Error::Rewrite)
}
/// If the axon input represents a comp, parse it and return a `String`
/// which contains formatted code.
///
/// The `axon` argument to this function should be a string containing the
/// output of running `<some comp src>.parseAst.toAxonCode` in SkySpark.
///
/// # Example
/// ```rust
/// use axon_parser::format_comp;
///
/// let desired_width = 80;
/// let axon = r###"{type:"compdef", params:[{name:"cells"}], body:{type:"block", exprs:[{type:"var", name:"in"}]}, cells:{in:{defVal:0}}}"###;
/// let formatted_code = format_comp(axon, desired_width).unwrap();
/// let expected_code = "defcomp\n in: {defVal: 0}\n\n do\n in\n end\nend";
/// assert_eq!(formatted_code, expected_code);
/// ```
///
pub fn format_comp(axon: &str, desired_width: usize) -> Result<String, Error> {
let comp = parse_comp(axon)?;
let context = fmt::Context::new(0, desired_width);
let widen = true;
let code = comp.default_rewrite(context, widen);
code.ok_or(Error::Rewrite)
}
// #[cfg(test)]
// mod tests {
// #[test]
// fn it_works() {
// let code = include_str!("./test2.txt");
// let x = crate::format(code, 80).unwrap();
// println!("{}", x);
// }
// }