Validate input in Term::new
diff --git a/src/stable.rs b/src/stable.rs
index abfeab3..ad9870c 100644
--- a/src/stable.rs
+++ b/src/stable.rs
@@ -403,6 +403,8 @@
impl Term {
pub fn new(string: &str, span: Span) -> Term {
+ validate_term(string);
+
Term {
intern: SYMBOLS.with(|s| s.borrow_mut().intern(string)),
span: span,
@@ -426,6 +428,42 @@
}
}
+fn validate_term(string: &str) {
+ let validate = if string.starts_with('\'') {
+ &string[1..]
+ } else if string.starts_with("r#") {
+ &string[2..]
+ } else {
+ string
+ };
+
+ if validate.is_empty() {
+ panic!("Term is not allowed to be empty; use Option<Term>");
+ }
+
+ if validate.bytes().all(|digit| digit >= b'0' && digit <= b'9') {
+ panic!("Term cannot be a number; use Literal instead");
+ }
+
+ fn xid_ok(string: &str) -> bool {
+ let mut chars = string.chars();
+ let first = chars.next().unwrap();
+ if !(UnicodeXID::is_xid_start(first) || first == '_') {
+ return false;
+ }
+ for ch in chars {
+ if !UnicodeXID::is_xid_continue(ch) {
+ return false;
+ }
+ }
+ true
+ }
+
+ if !xid_ok(validate) {
+ panic!("{:?} is not a valid Term", string);
+ }
+}
+
impl fmt::Debug for Term {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Term").field(&self.as_str()).finish()