sim_lib_forge/
normalize.rs1use sim_kernel::{ContentId, Datum, Error, Expr, Result};
2
3pub fn normalize_prose(prose: &str) -> Result<(String, ContentId)> {
10 let normalized = collapse_ascii_whitespace(prose);
11 if normalized.is_empty() {
12 return Err(Error::Eval("forge lift prose must not be empty".to_owned()));
13 }
14 Ok((normalized.clone(), source_content_id(&normalized)?))
15}
16
17fn collapse_ascii_whitespace(prose: &str) -> String {
18 let mut out = String::with_capacity(prose.len());
19 let mut pending_space = false;
20
21 for ch in prose.chars() {
22 if ch.is_ascii_whitespace() {
23 if !out.is_empty() {
24 pending_space = true;
25 }
26 continue;
27 }
28 if pending_space {
29 out.push(' ');
30 pending_space = false;
31 }
32 out.push(ch);
33 }
34
35 out
36}
37
38fn source_content_id(normalized: &str) -> Result<ContentId> {
39 Datum::try_from(Expr::String(normalized.to_owned()))?.content_id()
40}