Repository: typst/typst
File: crates/typst-library/src/introspection/counter.rs (Rust)

Code before:
        numbering: &Numbering,
        span: Span,
    ) -> SourceResult<Content> {
        let context = Context::new(Some(loc), Some(styles));
        Ok(engine
            .introspect(CounterAtIntrospection(self.clone(), loc, span))?
            .display(engine, context.track(), numbering)?
            .display())
    }

    /// Resolves the numbering for this counter track.
    ///
    /// This coupling between the counter type and the remaining standard
    /// library is not great ...
    fn matching_numbering(
        &self,
        engine: &mut Engine,
        styles: StyleChain,
        loc: Location,
        span: Span,
    ) -> Option<Numbering> {
        match self.0 {
            CounterKey::Page => loc.page_numbering(engine, span),
            CounterKey::Selector(Selector::Elem(func, _)) => engine
                .introspect(QueryUniqueIntrospection(Selector::Location(loc), span))
                .map_or_else(
                    |_| {
                        if func == HeadingElem::ELEM {
                            styles.get_cloned(HeadingElem::numbering)
                        } else if func == FigureElem::ELEM {
                            styles.get_cloned(FigureElem::numbering)
                        } else if func == EquationElem::ELEM {
                            styles.get_cloned(EquationElem::numbering)
                        } else if func == FootnoteElem::ELEM {
                            Some(styles.get_cloned(FootnoteElem::numbering))
                        } else {
                            None
                        }
                    },
                    |content| {
                        if func == HeadingElem::ELEM {
                            content
                                .to_packed::<HeadingElem>()
                                .and_then(|elem| elem.numbering.as_option().clone())
                                .flatten()
                        } else if func == FigureElem::ELEM {
                            content
                                .to_packed::<FigureElem>()
                                .and_then(|elem| elem.numbering.as_option().clone())
                                .flatten()
                        } else if func == EquationElem::ELEM {

Review comment (bug):
~~Ignoring the error here is probably a problem, I think? But I need to deal with the case where no specific piece of content could be found at the location...~~

I used `QueryFirstIntrospection` instead since it returns `Option<Content>`

Code after:
        numbering: &Numbering,
        span: Span,
    ) -> SourceResult<Content> {
        let context = Context::new(Some(loc), Some(styles));
        Ok(engine
            .introspect(CounterAtIntrospection(self.clone(), loc, span))?
            .display(engine, context.track(), numbering)?
            .display())
    }

    /// Resolves the numbering for this counter track.
    ///
    /// This coupling between the counter type and the remaining standard
    /// library is not great ...
    fn matching_numbering(
        &self,
        engine: &mut Engine,
        styles: StyleChain,
        loc: Location,
        span: Span,
    ) -> Option<Numbering> {
        match self.0 {
            CounterKey::Page => loc.page_numbering(engine, span),
            CounterKey::Selector(Selector::Elem(func, _)) => engine
                .introspect(QueryFirstIntrospection(Selector::Location(loc), span))
                .and_then(|content| {
                    if func == HeadingElem::ELEM {
                        content
                            .to_packed::<HeadingElem>()
                            .and_then(|elem| elem.numbering.as_option().clone())
                            .flatten()
                    } else if func == FigureElem::ELEM {
                        content
                            .to_packed::<FigureElem>()
                            .and_then(|elem| elem.numbering.as_option().clone())
                            .flatten()
                    } else if func == EquationElem::ELEM {
                        content
                            .to_packed::<EquationElem>()
                            .and_then(|elem| elem.numbering.as_option().clone())
                            .flatten()
                    } else if func == FootnoteElem::ELEM {
                        content
                            .to_packed::<FootnoteElem>()
                            .and_then(|elem| elem.numbering.as_option().clone())
                    } else {
                        None
                    }
                })
                .or_else(|| {
                    if func == HeadingElem::ELEM {