diff --git a/lib/rust/parser/jni/src/lib.rs b/lib/rust/parser/jni/src/lib.rs index 4ea8cba67b2..07d2e6081d1 100644 --- a/lib/rust/parser/jni/src/lib.rs +++ b/lib/rust/parser/jni/src/lib.rs @@ -59,7 +59,10 @@ pub extern "system" fn Java_org_enso_syntax2_Parser_parseInput( let mut code = input; let mut meta = None; if let Some((meta_, code_)) = enso_parser::metadata::parse(input) { - meta = Some(meta_); + match meta_ { + Ok(meta_) => meta = Some(meta_), + Err(e) => error!("Ignoring invalid metadata: {e}."), + } code = code_; } state.base = str::as_ptr(code) as usize as u64; @@ -73,7 +76,7 @@ pub extern "system" fn Java_org_enso_syntax2_Parser_parseInput( default() } }; - state.metadata = meta.and_then(|meta| meta.ok()); + state.metadata = meta; let result = env.new_direct_byte_buffer(&mut state.output); result.unwrap().into_inner() } diff --git a/lib/rust/parser/src/metadata.rs b/lib/rust/parser/src/metadata.rs index 905349108c6..6af557b7e93 100644 --- a/lib/rust/parser/src/metadata.rs +++ b/lib/rust/parser/src/metadata.rs @@ -7,6 +7,8 @@ use std::collections::BTreeMap; use std::str::FromStr; use uuid::Uuid; +const MARKER: &str = "#### METADATA ####\n"; + // ================ @@ -46,7 +48,7 @@ impl From for Metadata { /// Given source code, if a metadata section is found: Attempt to parse it; return the result, and /// the non-metadata portion of the input. pub fn parse(input: &str) -> Option<(Result, &str)> { - let (code, metadata) = input.rsplit_once("#### METADATA ####\n")?; + let (code, metadata) = input.rsplit_once(MARKER)?; Some((metadata.parse().map(|data: MetadataFormat| data.into()), code)) } @@ -57,7 +59,8 @@ impl FromStr for MetadataFormat { type Err = String; fn from_str(s: &str) -> Result { let mut lines = s.lines(); - let id_map = serde_json::from_str(lines.next().unwrap()).unwrap(); + let line0 = lines.next().ok_or("Expected a value.")?; + let id_map = serde_json::from_str(line0).map_err(|e| e.to_string())?; Ok(MetadataFormat { id_map }) } } @@ -78,3 +81,19 @@ struct Location { struct Number { value: usize, } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn bad_metadata() { + MetadataFormat::from_str(MARKER).expect_err("Empty metadata is error."); + MetadataFormat::from_str("[ , ]").expect_err("Invalid JSON is error."); + } + + #[test] + fn empty_metadata() { + MetadataFormat::from_str("[]").expect("Empty sequence is valid."); + } +}