From 19196dd4323e288b28678c1b86adc7a3e830f591 Mon Sep 17 00:00:00 2001 From: Kevin Nakamura Date: Sun, 25 Feb 2024 15:05:43 +0900 Subject: [PATCH] Duplicates in sets is now an Error. Clojure's behavior: (clojure.edn/read-string "#{1 2 2 3}") java.lang.IllegalArgumentException: Duplicate key: 2 [at :1:1] --- src/deserialize/parse.rs | 11 ++++++++--- src/edn/error.rs | 1 + tests/error_messages.rs | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/deserialize/parse.rs b/src/deserialize/parse.rs index bc36479..79ed7d2 100644 --- a/src/deserialize/parse.rs +++ b/src/deserialize/parse.rs @@ -262,9 +262,14 @@ fn parse_set(walker: &mut Walker<'_>) -> Result { } Some(_) => { let next = parse_internal(walker)?; - if next != Edn::Empty { - set.insert(next); - } + if next != Edn::Empty && !set.insert(next) { + return Err(Error { + code: Code::SetDuplicateKey, + line: Some(walker.line), + column: Some(walker.column), + ptr: Some(walker.ptr), + }); + }; } _ => { return Err(Error { diff --git a/src/edn/error.rs b/src/edn/error.rs index a8e9d15..a186bf5 100644 --- a/src/edn/error.rs +++ b/src/edn/error.rs @@ -20,6 +20,7 @@ pub enum Code { /// Parse errors HashMapDuplicateKey, + SetDuplicateKey, InvalidChar, InvalidEscape, InvalidKeyword, diff --git a/tests/error_messages.rs b/tests/error_messages.rs index 8e30916..13ac985 100644 --- a/tests/error_messages.rs +++ b/tests/error_messages.rs @@ -94,4 +94,21 @@ world!"# let small = edn_rs::from_edn::(&Edn::UInt(9876123)); assert_eq!(format!("{small:?}"), "Err(EdnError { code: TryFromInt(TryFromIntError(())), line: None, column: None, ptr: None })"); } + + #[test] + #[cfg(feature = "sets")] + fn duplicate_in_set() { + assert_eq!( + err_as_string("#{1 42 42 3}"), + "EdnError { code: SetDuplicateKey, line: Some(1), column: Some(10), ptr: Some(9) }" + ); + } + + #[test] + fn duplicate_in_map() { + assert_eq!( + err_as_string("{:foo 42 :bar 43 :foo \"cat\"}"), + "EdnError { code: HashMapDuplicateKey, line: Some(1), column: Some(28), ptr: Some(27) }" + ); + } }