summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNadrieril2020-04-09 23:09:47 +0100
committerNadrieril2020-04-09 23:10:36 +0100
commitda80ef06a91e3869cc3c1d4dbd07259c408ff490 (patch)
tree76c2406150a3c46d6b7281ca3503d1a859a25e3d
parent96bc42f4d7aa6746658e2da3bf6a6125e275c231 (diff)
Move Label escaping out of its Display impl
-rw-r--r--dhall/src/syntax/text/printer.rs54
-rw-r--r--dhall/tests/normalization/success/regression/ToMapQuotedFieldsA.dhall1
-rw-r--r--dhall/tests/normalization/success/regression/ToMapQuotedFieldsB.dhall1
-rw-r--r--serde_dhall/tests/de.rs16
4 files changed, 49 insertions, 23 deletions
diff --git a/dhall/src/syntax/text/printer.rs b/dhall/src/syntax/text/printer.rs
index 9e90660..ccba385 100644
--- a/dhall/src/syntax/text/printer.rs
+++ b/dhall/src/syntax/text/printer.rs
@@ -146,6 +146,21 @@ where
f.write_str(close)
}
+fn fmt_label(label: &Label, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ // TODO: distinguish between reserved and nonreserved locations for quoting builtins
+ let s = String::from(label);
+ let is_reserved = match s.as_str() {
+ "let" | "in" | "if" | "then" | "else" | "Type" | "Kind" | "Sort"
+ | "True" | "False" | "Some" => true,
+ _ => Builtin::parse(&s).is_some(),
+ };
+ if !is_reserved && s.chars().all(|c| c.is_ascii_alphanumeric()) {
+ write!(f, "{}", s)
+ } else {
+ write!(f, "`{}`", s)
+ }
+}
+
/// Generic instance that delegates to subexpressions
impl<SE: Display + Clone> Display for ExprKind<SE> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
@@ -153,16 +168,21 @@ impl<SE: Display + Clone> Display for ExprKind<SE> {
match self {
Var(a) => a.fmt(f)?,
Lam(a, b, c) => {
- write!(f, "λ({} : {}) → {}", a, b, c)?;
+ write!(f, "λ(")?;
+ fmt_label(a, f)?;
+ write!(f, " : {}) → {}", b, c)?;
}
Pi(a, b, c) if &String::from(a) == "_" => {
write!(f, "{} → {}", b, c)?;
}
Pi(a, b, c) => {
- write!(f, "∀({} : {}) → {}", a, b, c)?;
+ write!(f, "∀(")?;
+ fmt_label(a, f)?;
+ write!(f, " : {}) → {}", b, c)?;
}
Let(a, b, c, d) => {
- write!(f, "let {}", a)?;
+ write!(f, "let ")?;
+ fmt_label(a, f)?;
if let Some(b) = b {
write!(f, " : {}", b)?;
}
@@ -183,14 +203,16 @@ impl<SE: Display + Clone> Display for ExprKind<SE> {
}
RecordLit(a) if a.is_empty() => f.write_str("{=}")?,
RecordLit(a) => fmt_list("{ ", ", ", " }", a, f, |(k, v), f| {
- write!(f, "{} = {}", k, v)
+ fmt_label(k, f)?;
+ write!(f, " = {}", v)
})?,
RecordType(a) if a.is_empty() => f.write_str("{}")?,
RecordType(a) => fmt_list("{ ", ", ", " }", a, f, |(k, t), f| {
- write!(f, "{} : {}", k, t)
+ fmt_label(k, f)?;
+ write!(f, " : {}", t)
})?,
UnionType(a) => fmt_list("< ", " | ", " >", a, f, |(k, v), f| {
- write!(f, "{}", k)?;
+ fmt_label(k, f)?;
if let Some(v) = v {
write!(f, ": {}", v)?;
}
@@ -238,11 +260,12 @@ impl<SE: Display + Clone> Display for OpKind<SE> {
}
}
Field(a, b) => {
- write!(f, "{}.{}", a, b)?;
+ write!(f, "{}.", a)?;
+ fmt_label(b, f)?;
}
Projection(e, ls) => {
write!(f, "{}.", e)?;
- fmt_list("{ ", ", ", " }", ls, f, Display::fmt)?;
+ fmt_list("{ ", ", ", " }", ls, f, fmt_label)?;
}
ProjectionByExpr(a, b) => {
write!(f, "{}.({})", a, b)?;
@@ -379,18 +402,7 @@ impl Display for NaiveDouble {
impl Display for Label {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
- // TODO: distinguish between reserved and nonreserved locations for quoting builtins
- let s = String::from(self);
- let is_reserved = match s.as_str() {
- "let" | "in" | "if" | "then" | "else" | "Type" | "Kind"
- | "Sort" | "True" | "False" | "Some" => true,
- _ => Builtin::parse(&s).is_some(),
- };
- if !is_reserved && s.chars().all(|c| c.is_ascii_alphanumeric()) {
- write!(f, "{}", s)
- } else {
- write!(f, "`{}`", s)
- }
+ write!(f, "{}", String::from(self))
}
}
@@ -495,7 +507,7 @@ impl Display for Scheme {
impl Display for V {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let V(x, n) = self;
- x.fmt(f)?;
+ fmt_label(x, f)?;
if *n != 0 {
write!(f, "@{}", n)?;
}
diff --git a/dhall/tests/normalization/success/regression/ToMapQuotedFieldsA.dhall b/dhall/tests/normalization/success/regression/ToMapQuotedFieldsA.dhall
new file mode 100644
index 0000000..2b355fa
--- /dev/null
+++ b/dhall/tests/normalization/success/regression/ToMapQuotedFieldsA.dhall
@@ -0,0 +1 @@
+toMap { `if` = 0, `foo%bar` = 1 }
diff --git a/dhall/tests/normalization/success/regression/ToMapQuotedFieldsB.dhall b/dhall/tests/normalization/success/regression/ToMapQuotedFieldsB.dhall
new file mode 100644
index 0000000..d71242b
--- /dev/null
+++ b/dhall/tests/normalization/success/regression/ToMapQuotedFieldsB.dhall
@@ -0,0 +1 @@
+[ { mapKey = "foo%bar", mapValue = 1 }, { mapKey = "if", mapValue = 0 } ]
diff --git a/serde_dhall/tests/de.rs b/serde_dhall/tests/de.rs
index a5c42fd..41b4080 100644
--- a/serde_dhall/tests/de.rs
+++ b/serde_dhall/tests/de.rs
@@ -60,6 +60,9 @@ fn test_de_typed() {
#[test]
fn test_de_untyped() {
+ use std::collections::BTreeMap;
+ use std::collections::HashMap;
+
fn parse<T: FromDhall>(s: &str) -> T {
from_str(s).parse().unwrap()
}
@@ -70,7 +73,6 @@ fn test_de_untyped() {
(1, "foo".to_owned(), 42)
);
- use std::collections::HashMap;
let mut expected_map = HashMap::new();
expected_map.insert("x".to_string(), 1);
expected_map.insert("y".to_string(), 2);
@@ -79,7 +81,17 @@ fn test_de_untyped() {
expected_map
);
- use std::collections::BTreeMap;
+ let mut expected_map = HashMap::new();
+ expected_map.insert("if".to_string(), 1);
+ expected_map.insert("FOO_BAR".to_string(), 2);
+ expected_map.insert("baz-kux".to_string(), 3);
+ assert_eq!(
+ parse::<HashMap<String, usize>>(
+ "{ `if` = 1, FOO_BAR = 2, baz-kux = 3 }"
+ ),
+ expected_map
+ );
+
let mut expected_map = BTreeMap::new();
expected_map.insert("x".to_string(), 1);
expected_map.insert("y".to_string(), 2);