Repository: typst/typst
File: crates/typst-library/src/model/bibliography.rs (Rust)

Code before:
                    style,
                    typst_utils::hash128(&(TypeId::of::<Bytes>(), bytes)),
                )))
            })
            .map_err(|err| {
                LoadError::new(ReportPos::None, "failed to load CSL style", err)
            })
    }

    /// Get the underlying independent style.
    pub fn get(&self) -> &citationberg::IndependentStyle {
        self.0.as_ref()
    }
}

/// Source for a CSL style.
#[derive(Debug, Clone, PartialEq, Hash)]
pub enum CslSource {
    /// A predefined named style.
    Named(ArchivedStyle),
    /// A normal data source.
    Normal(DataSource),
}

/// Parses and checks for a deprecated CSL style.
pub(super) fn check_csl_style<T: FromValue<Spanned<Value>>>(
    value: Option<Spanned<Value>>,
    engine: &mut Engine,
) -> SourceResult<Option<T>> {
    let Some(value) = value else {
        return Ok(None);
    };

    if let Value::Str(style) = &value.v
        && &**style == "chicago-fullnotes"
    {
        engine.sink.warn(crate::diag::warning!(
            value.span,
            "style 'chicago-fullnotes' has been deprecated in favor of 'chicago-notes'"
        ));
    }

    let span = value.span;

    T::from_value(value).at(span).map(Some)
}

impl Reflect for CslSource {
    #[comemo::memoize]
    fn input() -> CastInfo {
        let source = std::iter::once(DataSource::input());

Review comment (bug):
could this be integrated into `CslStyle::load`? intuitively that would feel cleaner to me at first glance, but I might be wrong.

Code after:
        citationberg::IndependentStyle::from_xml(text)
            .map(|style| {
                Self(Arc::new(ManuallyHash::new(
                    style,
                    typst_utils::hash128(&(TypeId::of::<Bytes>(), bytes)),
                )))
            })
            .map_err(|err| {
                LoadError::new(ReportPos::None, "failed to load CSL style", err)
            })
    }

    /// Get the underlying independent style.
    pub fn get(&self) -> &citationberg::IndependentStyle {
        self.0.as_ref()
    }
}

/// Source for a CSL style.
#[derive(Debug, Clone, PartialEq, Hash)]
pub enum CslSource {
    /// A predefined named style and potentially a deprecation warning.
    Named(ArchivedStyle, Option<&'static str>),
    /// A normal data source.
    Normal(DataSource),
}

impl Reflect for CslSource {
    #[comemo::memoize]
    fn input() -> CastInfo {
        let source = std::iter::once(DataSource::input());

        /// All possible names and their short documentation for `ArchivedStyle`, including aliases.
        static ARCHIVED_STYLE_NAMES: LazyLock<Vec<(&&str, &'static str)>> =
            LazyLock::new(|| {
                ArchivedStyle::all()
                    .iter()
                    .flat_map(|name| {
                        let (main_name, aliases) = name
                            .names()
                            .split_first()
                            .expect("all ArchivedStyle should have at least one name");

                        std::iter::once((main_name, name.display_name())).chain(
                            aliases.iter().map(move |alias| {
                                // Leaking is okay here, because we are in a `LazyLock`.
                                let docs: &'static str = Box::leak(
                                    format!("A short alias of `{main_name}`")
                                        .into_boxed_str(),
                                );
                                (alias, docs)