clojure-reader 0.6.1

A Clojure reader
Documentation
use clojure_reader::edn;

fn err_as_string(s: &str) -> String {
	let err = edn::read_string(s).err().unwrap();
	format!("{err:?}")
}

#[test]
fn duplicates() {
	assert_eq!(
		err_as_string(
			"{:cat 42
                  :cat 0x42}"
		),
		"EdnError { code: HashMapDuplicateKey, line: Some(2), column: Some(28), ptr: Some(36) }"
	);
	assert_eq!(
		err_as_string("#{:cat 1 2 [42] 2}"),
		"EdnError { code: SetDuplicateKey, line: Some(1), column: Some(18), ptr: Some(17) }"
	);

	assert_eq!(
		err_as_string("{#foo :a 1 #foo :a 2}"),
		"EdnError { code: HashMapDuplicateKey, line: Some(1), column: Some(21), ptr: Some(20) }"
	);

	assert_eq!(
		err_as_string("#{#bar :x #bar :x}"),
		"EdnError { code: SetDuplicateKey, line: Some(1), column: Some(18), ptr: Some(17) }"
	);

	assert_eq!(
		err_as_string("{:a 1 :a [2]}"),
		"EdnError { code: HashMapDuplicateKey, line: Some(1), column: Some(13), ptr: Some(12) }"
	);
}

#[test]
fn unbalanced_forms() {
	assert_eq!(
		err_as_string("(car (cdr) cdrrdrdrr (so (many (parens ())))"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(45), ptr: Some(44) }"
	);

	assert_eq!(
		err_as_string("{:foo 42 :bar)"),
		"EdnError { code: UnmatchedDelimiter(')'), line: Some(1), column: Some(14), ptr: Some(13) }"
	);

	assert_eq!(
		err_as_string("#inst"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(6), ptr: Some(5) }"
	);

	assert_eq!(
		err_as_string("{:a 1 :a 2"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(11), ptr: Some(10) }"
	);

	assert_eq!(
		err_as_string("#{1 1"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(6), ptr: Some(5) }"
	);
}

#[test]
fn parse_invalid_ints() {
	assert_eq!(
		err_as_string("42invalid123"),
		"EdnError { code: InvalidNumber, line: Some(1), column: Some(1), ptr: Some(0) }"
	);
	assert_eq!(
		err_as_string("0xxyz123"),
		"EdnError { code: InvalidNumber, line: Some(1), column: Some(1), ptr: Some(0) }"
	);
	assert_eq!(
		err_as_string("42rabcxzy"),
		"EdnError { code: InvalidRadix(Some(42)), line: Some(1), column: Some(1), ptr: Some(0) }"
	);
	assert_eq!(
		err_as_string("42crazyrabcxzy"),
		"EdnError { code: InvalidRadix(None), line: Some(1), column: Some(1), ptr: Some(0) }"
	);
}

#[test]
fn test_invalid_radix() {
	assert_eq!(
		err_as_string("4r42"),
		"EdnError { code: InvalidNumber, line: Some(1), column: Some(1), ptr: Some(0) }"
	);
	assert_eq!(
		err_as_string("0x4.20"),
		"EdnError { code: InvalidNumber, line: Some(1), column: Some(1), ptr: Some(0) }"
	);
}

#[test]
fn parse_tag_no_end() {
	assert_eq!(
		err_as_string(r"#Unit"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(6), ptr: Some(5) }"
	);
	assert_eq!(
		err_as_string(r#"#Unit "lolnoendingquote"#),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(24), ptr: Some(23) }"
	);
	assert_eq!(
		err_as_string(r"#Unit ;"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(8), ptr: Some(7) }"
	);
}

#[test]
fn parse_symbol_with_quotes() {
	assert_eq!(
		err_as_string(r#"[thingy" c]"#),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(12), ptr: Some(11) }"
	);

	assert_eq!(
		err_as_string(r#"{"thingy c}"#),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(12), ptr: Some(11) }"
	);

	assert_eq!(
		err_as_string(
			r#"[thingy\"
c]"#
		),
		"EdnError { code: UnexpectedEOF, line: Some(2), column: Some(3), ptr: Some(12) }"
	);
}

#[test]
fn unmatched_closing_delimiter_at_top_level() {
	assert_eq!(
		err_as_string("}"),
		"EdnError { code: UnmatchedDelimiter('}'), line: Some(1), column: Some(1), ptr: Some(0) }"
	);
}

#[test]
fn unmatched_delimiter_in_tag_context() {
	assert_eq!(
		err_as_string("#tag }"),
		"EdnError { code: UnmatchedDelimiter('}'), line: Some(1), column: Some(6), ptr: Some(5) }"
	);
}

#[test]
fn map_with_odd_elements() {
	assert_eq!(
		err_as_string("{:a}"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(4), ptr: Some(3) }"
	);
}

#[test]
fn test_unexpected_eof_in_tag() {
	assert_eq!(
		err_as_string("#tag "),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(6), ptr: Some(5) }"
	);
}

#[test]
fn parse_discard_no_end() {
	assert_eq!(
		err_as_string("#{ #_ }"),
		"EdnError { code: UnmatchedDelimiter('}'), line: Some(1), column: Some(7), ptr: Some(6) }"
	);
}

#[test]
fn test_unexpected_eof_in_discard() {
	assert_eq!(
		err_as_string("#_"),
		"EdnError { code: UnexpectedEOF, line: Some(1), column: Some(3), ptr: Some(2) }"
	);
}