script-meditate 0.1.0

Supercharge Cargo scripts with inline structured data/configuration.
Documentation
//! This crate is intended to be used in (currently unstable) [Cargo
//! scripts](https://doc.rust-lang.org/cargo/reference/unstable.html#script).
//! It allows you to provide structured data and configuration inside a frontmatter comment, which
//! can be parsed and obtained using a utility macro.
//!
//! # Data format support
//!
//! JSON, TOML, and YAML are currently supported.
//! The desired format(s) must be enabled [through Cargo features](#frontmatter-format-selection).
//! The type expected from parsing must implement [`Deserialize`](serde::Deserialize).
//!
//! The frontmatter comment is detected using the following pattern: `/*${tag}\n`, where `${tag}`
//! is `json`, `toml`, or `yaml` (case-sensitive). The end of the frontmatter comment is detected
//! using `\n*/\n` and must therefore not be found inside the data.
//!
//! # Note
//!
//! The script must not be placed directly inside the user's home directory.
//!
//! # Features
#![cfg_attr(feature = "doc", doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![deny(clippy::pedantic)]
#![deny(missing_docs)]

#[cfg(feature = "json")]
mod json;
#[cfg(feature = "json")]
#[doc(hidden)]
pub use json::serde_json;

#[cfg(feature = "toml")]
mod toml;
#[cfg(feature = "toml")]
#[doc(hidden)]
pub use toml::serde_toml;

#[cfg(feature = "yaml")]
mod yaml;
#[cfg(feature = "yaml")]
#[doc(hidden)]
pub use yaml::serde_yaml;

// Assumes that `\n*/\n` is not part of the JSON data.
#[doc(hidden)]
#[must_use]
pub fn extract_frontmatter<'s>(source: &'s str, tag: &str) -> Option<&'s str> {
    let start_pattern = format!("/*{tag}\n");
    let end_pattern = "\n*/\n";
    let from_comment_start = source.split_once(&start_pattern)?.1;
    Some(from_comment_start.split_once(end_pattern)?.0)
}

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

    #[test]
    fn test_json_frontmatter_extraction() {
        let source = r"
/*json
{
}
*/
";

        assert_eq!(extract_frontmatter(source, "json"), Some("{\n}"));
    }

    #[test]
    fn test_no_frontmatter_found() {
        let source = r"
/*
{
}
*/
";

        assert_eq!(extract_frontmatter(source, "json"), None);
    }
}