toml_test_data/
lib.rs

1//! Test cases from the [toml-test](https://github.com/toml-lang/toml-test) conformance suite
2//!
3//! To read and write these test cases, see [`toml-test`](https://docs.rs/toml-test).
4//!
5//! To run the test cases against your TOML implementation, see [`toml-test-harness`](https://docs.rs/toml-test-harness).
6
7#![cfg_attr(docsrs, feature(doc_cfg))]
8#![warn(clippy::print_stderr)]
9#![warn(clippy::print_stdout)]
10#![allow(clippy::self_named_module_files)] // `include_dir!`?
11
12use std::borrow::Cow;
13
14const TESTS_DIR: include_dir::Dir<'_> =
15    include_dir::include_dir!("$CARGO_MANIFEST_DIR/assets/toml-test/tests");
16
17/// Get the test cases for a given spec version
18pub fn version(ver: &str) -> impl Iterator<Item = &'static std::path::Path> {
19    TESTS_DIR
20        .get_file(format!("files-toml-{ver}"))
21        .and_then(|f| std::str::from_utf8(f.contents()).ok())
22        .into_iter()
23        .flat_map(|f| f.lines())
24        .map(std::path::Path::new)
25}
26
27/// Get all supported spec versions and their test cases
28pub fn versions() -> std::collections::HashMap<&'static str, Vec<&'static std::path::Path>> {
29    TESTS_DIR
30        .files()
31        .filter_map(|f| {
32            let name = f.path().file_name()?;
33            let version = name.to_str()?.strip_prefix("files-toml-")?;
34            let paths = std::str::from_utf8(f.contents())
35                .ok()?
36                .lines()
37                .map(std::path::Path::new)
38                .collect::<Vec<_>>();
39            Some((version, paths))
40        })
41        .collect()
42}
43
44/// Valid TOML test case
45#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct Valid<'a> {
47    pub name: Cow<'a, std::path::Path>,
48    pub fixture: Cow<'a, [u8]>,
49    pub expected: Cow<'a, [u8]>,
50}
51
52impl<'a> Valid<'a> {
53    pub fn borrow<'b: 'a>(&'b self) -> Valid<'b> {
54        Self {
55            name: Cow::Borrowed(self.name()),
56            fixture: Cow::Borrowed(self.fixture()),
57            expected: Cow::Borrowed(self.expected()),
58        }
59    }
60
61    pub fn name(&self) -> &std::path::Path {
62        self.name.as_ref()
63    }
64
65    pub fn fixture(&self) -> &[u8] {
66        self.fixture.as_ref()
67    }
68
69    pub fn expected(&self) -> &[u8] {
70        self.expected.as_ref()
71    }
72}
73
74/// Returns all [`Valid`] TOML test cases
75pub fn valid() -> impl Iterator<Item = Valid<'static>> {
76    let valid_dir = TESTS_DIR.get_dir("valid").unwrap();
77    valid_files(valid_dir).chain(valid_dir.dirs().flat_map(|d| {
78        assert_eq!(d.dirs().count(), 0);
79        valid_files(d)
80    }))
81}
82
83fn valid_files<'d>(
84    dir: &'d include_dir::Dir<'static>,
85) -> impl Iterator<Item = Valid<'static>> + 'd {
86    dir.files()
87        .filter(|f| f.path().extension().unwrap_or_default() == "toml")
88        .map(move |f| {
89            let t = f;
90            let j = dir
91                .files()
92                .find(|f| {
93                    f.path().parent() == t.path().parent()
94                        && f.path().file_stem() == t.path().file_stem()
95                        && f.path().extension().unwrap() == "json"
96                })
97                .unwrap();
98            let name = Cow::Borrowed(t.path());
99            let fixture = Cow::Borrowed(t.contents());
100            let expected = Cow::Borrowed(j.contents());
101            Valid {
102                name,
103                fixture,
104                expected,
105            }
106        })
107}
108
109/// Invalid TOML test case
110#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct Invalid<'a> {
112    pub name: Cow<'a, std::path::Path>,
113    pub fixture: Cow<'a, [u8]>,
114}
115
116impl<'a> Invalid<'a> {
117    pub fn borrow<'b: 'a>(&'b self) -> Invalid<'b> {
118        Self {
119            name: Cow::Borrowed(self.name()),
120            fixture: Cow::Borrowed(self.fixture()),
121        }
122    }
123
124    pub fn name(&self) -> &std::path::Path {
125        self.name.as_ref()
126    }
127
128    pub fn fixture(&self) -> &[u8] {
129        self.fixture.as_ref()
130    }
131}
132
133/// Returns all [`Invalid`] TOML test cases
134pub fn invalid() -> impl Iterator<Item = Invalid<'static>> {
135    let invalid_dir = TESTS_DIR.get_dir("invalid").unwrap();
136    assert_eq!(invalid_dir.files().count(), 0);
137    invalid_dir.dirs().flat_map(|d| {
138        assert_eq!(d.dirs().count(), 0);
139        d.files().map(|f| {
140            let t = f;
141            let name = Cow::Borrowed(f.path());
142            let fixture = Cow::Borrowed(t.contents());
143            Invalid { name, fixture }
144        })
145    })
146}
147
148#[doc = include_str!("../README.md")]
149#[cfg(doctest)]
150pub struct ReadmeDoctests;