Skip to main content

urna_format/sections/
canonical.rs

1//! `chunks_canonical` section (`SECTION_CHUNKS_CANONICAL = 0x02`).
2//! One length-prefixed UTF-8 string per chunk - the canonical text the
3//! `chunk_id` was derived from.
4
5use super::codec::{Cursor, read_prefix, write_lp_str, write_prefix};
6use crate::error::UrnaError;
7use crate::layout::SECTION_CHUNKS_CANONICAL;
8
9pub fn encode_chunks_canonical(texts: &[String]) -> crate::Result<Vec<u8>> {
10    let mut buf = Vec::new();
11    write_prefix(&mut buf, texts.len() as u64);
12    for t in texts {
13        write_lp_str(&mut buf, t)?;
14    }
15    Ok(buf)
16}
17
18pub fn decode_chunks_canonical(data: &[u8], expected_count: usize) -> crate::Result<Vec<String>> {
19    let mut c = Cursor::new(data, SECTION_CHUNKS_CANONICAL);
20    let count = read_prefix(&mut c)? as usize;
21    if count != expected_count {
22        return Err(UrnaError::SectionCountMismatch {
23            section_id: SECTION_CHUNKS_CANONICAL,
24            expected: expected_count,
25            got: count,
26        });
27    }
28    let mut out = Vec::with_capacity(count);
29    for _ in 0..count {
30        out.push(c.read_lp_str()?);
31    }
32    c.finish()?;
33    Ok(out)
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn roundtrip() {
42        let texts = vec!["primeiro".to_string(), "segundo".to_string()];
43        let bytes = encode_chunks_canonical(&texts).unwrap();
44        let back = decode_chunks_canonical(&bytes, 2).unwrap();
45        assert_eq!(texts, back);
46    }
47}