alix 0.6.0

A learning tool built for understanding, not just remembering.
Documentation
use std::hash::Hasher;

use twox_hash::XxHash64;

use super::{closes_fence, collapse, fence_opener};

// A change here stales every persisted content fingerprint: deliberate, never
// a silent refactor.
pub fn canonical_content(front: &str, back: &[String]) -> String {
    let mut out = collapse(front);
    let mut fence: Option<char> = None;
    let mut prose = String::new();
    for line in back {
        if let Some(ch) = fence {
            out.push('\n');
            out.push_str(line);
            if closes_fence(line, ch) {
                fence = None;
            }
        } else if let Some(ch) = fence_opener(line) {
            if !prose.is_empty() {
                out.push('\n');
                out.push_str(&prose);
                prose.clear();
            }
            out.push('\n');
            out.push_str(line);
            fence = Some(ch);
        } else {
            let collapsed = collapse(line);
            if !collapsed.is_empty() {
                if !prose.is_empty() {
                    prose.push(' ');
                }
                prose.push_str(&collapsed);
            }
        }
    }
    if !prose.is_empty() {
        out.push('\n');
        out.push_str(&prose);
    }
    out
}

pub fn content_fingerprint(front: &str, back: &[String]) -> u64 {
    let mut hasher = XxHash64::default();
    hasher.write(canonical_content(front, back).as_bytes());
    hasher.finish()
}

pub(super) fn hash64(s: &str) -> u64 {
    let mut hasher = XxHash64::default();
    hasher.write(s.as_bytes());
    hasher.finish()
}