Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/gunnar-ui

crates/gunnar-ui-web/src/code.rs

//! **The code of a page, for the tests that can only read it** (stinky #22).
//!
//! The pages are `#[cfg(target_arch = "wasm32")]` and the host has no DOM, so
//! a few promises about them — this card swaps through that rule, that page
//! reads this route — are held to the page's source. A test that searched the
//! raw file went green when the words stood in a COMMENT, which is exactly
//! where a removed call leaves them. [`of`] is the source with every comment
//! taken out (string and char literals kept whole, a `//` inside a URL is not
//! a comment), so what such a test finds is code that compiles.
//!
//! Where a promise CAN be run — a rule in a host module, a route on the
//! server's router — it is a behaviour test instead, and not here.

/// `src` with its line, doc and (nested) block comments removed. A comment
/// becomes one space; a line comment keeps its newline.
pub fn of(src: &str) -> String {
    let b = src.as_bytes();
    let mut out = String::with_capacity(src.len());
    let mut i = 0;
    let mut kept = 0;
    let keep = |out: &mut String, from: usize, to: usize| out.push_str(&src[from..to]);
    while i < b.len() {
        if b[i..].starts_with(b"//") {
            keep(&mut out, kept, i);
            out.push(' ');
            i = b[i..].iter().position(|&x| x == b'\n').map_or(b.len(), |j| i + j);
            kept = i;
            continue;
        }
        if b[i..].starts_with(b"/*") {
            keep(&mut out, kept, i);
            out.push(' ');
            let mut depth = 0usize;
            while i < b.len() {
                if b[i..].starts_with(b"/*") {
                    depth += 1;
                    i += 2;
                } else if b[i..].starts_with(b"*/") {
                    depth -= 1;
                    i += 2;
                    if depth == 0 {
                        break;
                    }
                } else {
                    i += 1;
                }
            }
            kept = i;
            continue;
        }
        let c = b[i];
        if c == b'r' && (i == 0 || !(b[i - 1].is_ascii_alphanumeric() || b[i - 1] == b'_')) {
            let hashes = src[i + 1..].bytes().take_while(|&x| x == b'#').count();
            if b.get(i + 1 + hashes) == Some(&b'"') {
                let start = i + 2 + hashes;
                let close = format!("\"{}", "#".repeat(hashes));
                i = src[start..].find(&close).map_or(src.len(), |j| start + j + close.len());
                continue;
            }
        }
        if c == b'\'' {
            // A char literal ('"' included) or a lifetime.
            let rest = &src[i + 1..];
            match rest.chars().next() {
                Some('\\') => i += 1 + 2 + rest.get(2..).and_then(|r| r.find('\'')).map_or(0, |j| j + 1),
                Some(ch) if rest[ch.len_utf8()..].starts_with('\'') => i += 1 + ch.len_utf8() + 1,
                _ => i += 1,
            }
            continue;
        }
        if c == b'"' {
            i += 1;
            while i < b.len() && b[i] != b'"' {
                i += if b[i] == b'\\' { 2 } else { 1 };
            }
            i += 1;
            continue;
        }
        i += 1;
    }
    keep(&mut out, kept, src.len().min(i.max(kept)));
    out
}

#[cfg(test)]
mod tests {
    use super::of;

    /// ★ **Words in a comment are not code** — the way a scanner went green
    /// on a call that had been removed and left behind in a sentence.
    #[test]
    fn a_comment_is_not_code() {
        let src = "/// calls `machine::swap(` on every answer — ändå\n\
                   fn card() {\n    // machine::swap(&a, &b) was here\n    /* and /* nested */ machine::swap( */ draw();\n}\n";
        let code = of(src);
        assert!(!code.contains("machine::swap("), "{code}");
        assert!(code.contains("fn card()") && code.contains("draw();"), "{code}");
    }

    /// …while a string that holds `//` or `/*`, a raw string and a char
    /// literal are code, whole.
    #[test]
    fn literals_are_code_whole() {
        let src = r##"fn f() { let u = "https://x/api/server-key"; let r = r#"/* not "a" comment */"#; let q = '"'; let s = '/'; let å = '—'; g::<'a>(); } // gone"##;
        let code = of(src);
        assert!(code.contains(r#""https://x/api/server-key""#), "{code}");
        assert!(code.contains(r##"r#"/* not "a" comment */"#"##), "{code}");
        assert!(code.contains(r#"'"'"#) && code.contains("'/'") && code.contains("g::<'a>()") && code.contains("let å = '—';"), "{code}");
        assert!(!code.contains("gone"), "{code}");
    }
}