use super::*;
pub fn literal(input: &str) -> ParseResult<Value> {
fn normal(input: &str) -> ParseResult<&str> {
take_while1(|c: char| c.is_alphanumeric() || c == '.' || c == '_')(input)
}
fn with_paren(input: &str) -> ParseResult<&str> {
recognize(tuple((
terminated(alpha1, multispace0),
delimited(tag("("), delimited(multispace0, normal, multispace0), tag(")"))
)))(input)
}
satisfy(|c| c.is_alphabetic())(input)?;
let parser = alt((with_paren, normal)).map(|v| Value::Literal(v.into()));
context("literal", parser)(input)
}
pub fn string(input: &str) -> ParseResult<Value> {
fn quoted(qot: char) -> impl Fn(&str) -> ParseResult<&str> {
move |input: &str| {
delimited(
char(qot),
escaped(
take_till1(|c: char| c == '~' || c == qot),
'~',
anychar ),
char(qot)
)(input)
}
}
let double_quoted =
alt((quoted('"'), tag("\"\"").map(|_| ""))).map(|v| Value::DoubleQuotedString(v.into()));
let single_quoted =
alt((quoted('\''), tag("''").map(|_| ""))).map(|v| Value::SingleQuotedString(v.into()));
let parser = alt((double_quoted, single_quoted));
context("string", parser)(input)
}
pub fn number(input: &str) -> ParseResult<Value> { context("number", double.map(Value::Number))(input) }
pub fn list(input: &str) -> ParseResult<Value> {
let parser = delimited(
tag("("),
separated_list0(tag(","), delimited(multispace0, alt((string, literal, list, fail)), multispace0))
.map(Value::List),
tag(")")
);
context("list", parser)(input)
}
pub fn map(input: &str) -> ParseResult<Value> {
let parser = value_map.map(Value::Map);
context("map", parser)(input)
}