trustfall_rustdoc 0.39.0

Run Trustfall queries across multiple rustdoc JSON format versions.
Documentation
// AUTOGENERATED FROM template/versioned.rs.template; DO NOT EDIT DIRECTLY

use std::fmt::Debug;

use anyhow::bail;
use trustfall::Schema;

macro_rules! add_version_method {
    () => {
        pub fn version(&self) -> u32 {
            match self {
                #[cfg(feature = "v56")]
                Self::V56(..) => 56,

                #[cfg(feature = "v57")]
                Self::V57(..) => 57,

                #[cfg(feature = "v60")]
                Self::V60(..) => 60,
            }
        }
    };
}

#[non_exhaustive]
#[derive(Debug)]
pub enum VersionedStorage {
    #[cfg(feature = "v56")]
    V56(trustfall_rustdoc_adapter_v56::PackageStorage),

    #[cfg(feature = "v57")]
    V57(trustfall_rustdoc_adapter_v57::PackageStorage),

    #[cfg(feature = "v60")]
    V60(trustfall_rustdoc_adapter_v60::PackageStorage),
}

#[non_exhaustive]
#[derive(Debug)]
pub enum VersionedIndex<'a> {
    #[cfg(feature = "v56")]
    V56(trustfall_rustdoc_adapter_v56::PackageIndex<'a>),

    #[cfg(feature = "v57")]
    V57(trustfall_rustdoc_adapter_v57::PackageIndex<'a>),

    #[cfg(feature = "v60")]
    V60(trustfall_rustdoc_adapter_v60::PackageIndex<'a>),
}

#[non_exhaustive]
pub enum VersionedRustdocAdapter<'a> {
    #[cfg(feature = "v56")]
    V56(
        &'static Schema,
        trustfall_rustdoc_adapter_v56::RustdocAdapter<'a>,
    ),

    #[cfg(feature = "v57")]
    V57(
        &'static Schema,
        trustfall_rustdoc_adapter_v57::RustdocAdapter<'a>,
    ),

    #[cfg(feature = "v60")]
    V60(
        &'static Schema,
        trustfall_rustdoc_adapter_v60::RustdocAdapter<'a>,
    ),
}

impl VersionedStorage {
    /// The version of the crate held here, as reported by its rustdoc data.
    ///
    /// This is the version listed in the `Cargo.toml` of the crate, not its rustdoc format version.
    pub fn crate_version(&self) -> Option<&str> {
        match self {
            #[cfg(feature = "v56")]
            VersionedStorage::V56(s) => s.crate_version(),

            #[cfg(feature = "v57")]
            VersionedStorage::V57(s) => s.crate_version(),

            #[cfg(feature = "v60")]
            VersionedStorage::V60(s) => s.crate_version(),
        }
    }

    add_version_method!();
}

impl<'a> VersionedIndex<'a> {
    pub fn from_storage(storage: &'a VersionedStorage) -> Self {
        match storage {
            #[cfg(feature = "v56")]
            VersionedStorage::V56(s) => {
                Self::V56(trustfall_rustdoc_adapter_v56::PackageIndex::from_storage(s))
            }

            #[cfg(feature = "v57")]
            VersionedStorage::V57(s) => {
                Self::V57(trustfall_rustdoc_adapter_v57::PackageIndex::from_storage(s))
            }

            #[cfg(feature = "v60")]
            VersionedStorage::V60(s) => {
                Self::V60(trustfall_rustdoc_adapter_v60::PackageIndex::from_storage(s))
            }
        }
    }

    /// Build an index for Rust standard-library component rustdoc JSON.
    ///
    /// This opts into adapter-side standard-library stability rules. Use
    /// [`Self::from_storage`] for ordinary crates.
    pub fn from_rust_std_component_storage(storage: &'a VersionedStorage) -> Self {
        match storage {
            #[cfg(feature = "v56")]
            VersionedStorage::V56(s) => Self::V56(
                trustfall_rustdoc_adapter_v56::PackageIndex::from_rust_std_component_storage(s),
            ),

            #[cfg(feature = "v57")]
            VersionedStorage::V57(s) => Self::V57(
                trustfall_rustdoc_adapter_v57::PackageIndex::from_rust_std_component_storage(s),
            ),

            #[cfg(feature = "v60")]
            VersionedStorage::V60(s) => Self::V60(
                trustfall_rustdoc_adapter_v60::PackageIndex::from_rust_std_component_storage(s),
            ),
        }
    }

    add_version_method!();
}

impl<'a> VersionedRustdocAdapter<'a> {
    pub fn new(
        current: &'a VersionedIndex<'a>,
        baseline: Option<&'a VersionedIndex<'a>>,
    ) -> anyhow::Result<Self> {
        match (current, baseline) {
            #[cfg(feature = "v56")]
            (VersionedIndex::V56(c), Some(VersionedIndex::V56(b))) => {
                let adapter = trustfall_rustdoc_adapter_v56::RustdocAdapter::new(c, Some(b));
                Ok(VersionedRustdocAdapter::V56(
                    trustfall_rustdoc_adapter_v56::RustdocAdapter::schema(),
                    adapter,
                ))
            }

            #[cfg(feature = "v56")]
            (VersionedIndex::V56(c), None) => {
                let adapter = trustfall_rustdoc_adapter_v56::RustdocAdapter::new(c, None);
                Ok(VersionedRustdocAdapter::V56(
                    trustfall_rustdoc_adapter_v56::RustdocAdapter::schema(),
                    adapter,
                ))
            }

            #[cfg(feature = "v57")]
            (VersionedIndex::V57(c), Some(VersionedIndex::V57(b))) => {
                let adapter = trustfall_rustdoc_adapter_v57::RustdocAdapter::new(c, Some(b));
                Ok(VersionedRustdocAdapter::V57(
                    trustfall_rustdoc_adapter_v57::RustdocAdapter::schema(),
                    adapter,
                ))
            }

            #[cfg(feature = "v57")]
            (VersionedIndex::V57(c), None) => {
                let adapter = trustfall_rustdoc_adapter_v57::RustdocAdapter::new(c, None);
                Ok(VersionedRustdocAdapter::V57(
                    trustfall_rustdoc_adapter_v57::RustdocAdapter::schema(),
                    adapter,
                ))
            }

            #[cfg(feature = "v60")]
            (VersionedIndex::V60(c), Some(VersionedIndex::V60(b))) => {
                let adapter = trustfall_rustdoc_adapter_v60::RustdocAdapter::new(c, Some(b));
                Ok(VersionedRustdocAdapter::V60(
                    trustfall_rustdoc_adapter_v60::RustdocAdapter::schema(),
                    adapter,
                ))
            }

            #[cfg(feature = "v60")]
            (VersionedIndex::V60(c), None) => {
                let adapter = trustfall_rustdoc_adapter_v60::RustdocAdapter::new(c, None);
                Ok(VersionedRustdocAdapter::V60(
                    trustfall_rustdoc_adapter_v60::RustdocAdapter::schema(),
                    adapter,
                ))
            }

            #[allow(unreachable_patterns)]
            (c, Some(b)) => {
                bail!(
                    "version mismatch between current (v{}) and baseline (v{}) format versions",
                    c.version(),
                    b.version()
                )
            }
        }
    }

    pub fn schema(&self) -> &Schema {
        match self {
            #[cfg(feature = "v56")]
            VersionedRustdocAdapter::V56(schema, ..) => schema,

            #[cfg(feature = "v57")]
            VersionedRustdocAdapter::V57(schema, ..) => schema,

            #[cfg(feature = "v60")]
            VersionedRustdocAdapter::V60(schema, ..) => schema,
        }
    }

    add_version_method!();
}

pub(crate) fn supported_versions() -> &'static [u32] {
    &[
        #[cfg(feature = "v56")]
        56,
        #[cfg(feature = "v57")]
        57,
        #[cfg(feature = "v60")]
        60,
    ]
}