Skip to main content

varar_core/
doc_string_diff.rs

1//! Doc-string comparison — port of `doc-string-diff.ts` / `DocStringDiff.java`.
2
3use crate::error::StepError;
4use crate::span::Span;
5use crate::value::Value;
6
7/// A doc-string content difference: the fence body's span plus expected/actual.
8#[derive(Clone, Debug, PartialEq, Eq)]
9pub struct DocStringDiff {
10    pub span: Span,
11    pub expected: String,
12    pub actual: String,
13}
14
15impl DocStringDiff {
16    pub fn new(
17        span: Span,
18        expected: impl Into<String>,
19        actual: impl Into<String>,
20    ) -> DocStringDiff {
21        DocStringDiff {
22            span,
23            expected: expected.into(),
24            actual: actual.into(),
25        }
26    }
27}
28
29/// Compares a doc-string step's return against the fence body (exact equality,
30/// trailing newline included). `None` → no check. A non-string return →
31/// [`StepError::ReturnShape`].
32pub fn compare_doc_string(
33    returned: Option<&Value>,
34    content: &str,
35    span: Span,
36) -> Result<Option<DocStringDiff>, StepError> {
37    let s = match returned {
38        None => return Ok(None),
39        Some(Value::String(s)) => s,
40        Some(other) => {
41            return Err(StepError::ReturnShape(format!(
42                "expected a doc string (string), got {}",
43                other.type_name()
44            )));
45        }
46    };
47    if s == content {
48        Ok(None)
49    } else {
50        Ok(Some(DocStringDiff::new(span, content, s.clone())))
51    }
52}