Repository: typst/typst
File: crates/typst-library/src/visualize/image/svg.rs (Rust)

Code before:
                    select_fallback: Box::new(|c, exclude_fonts, db| {
                        font_resolver.lock().unwrap().select_fallback(
                            c,
                            exclude_fonts,
                            db,
                        )
                    }),
                },
                image_href_resolver: usvg::ImageHrefResolver {
                    resolve_data: usvg::ImageHrefResolver::default_data_resolver(),
                    resolve_string: Box::new(|href, _opts| {
                        image_resolver.lock().unwrap().load(href)
                    }),
                },
                ..base_options()
            },
        )
        .map_err(format_usvg_error)?;
        let font_hash = font_resolver.into_inner().unwrap().finish();
        let image_resolve_error = image_resolver.lock().unwrap().error.clone();
        match image_resolve_error {
            Some(err) => Err(err),
            None => {
                Ok(Self(Arc::new(Repr { data, size: tree_size(&tree), font_hash, tree })))
            }
        }
    }

    /// The raw image data.
    pub fn data(&self) -> &Bytes {
        &self.0.data
    }

    /// The SVG's width in pixels.
    pub fn width(&self) -> f64 {
        self.0.size.x
    }

    /// The SVG's height in pixels.
    pub fn height(&self) -> f64 {
        self.0.size.y
    }

    /// Accesses the usvg tree.
    pub fn tree(&self) -> &usvg::Tree {
        &self.0.tree
    }
}

impl Hash for Repr {
    fn hash<H: Hasher>(&self, state: &mut H) {

Review comment (suggestion):
I think an early return for the error case (with `if let Some(err)`) would be clearer here control-flow-wise.

Code after:
                    select_fallback: Box::new(|c, exclude_fonts, db| {
                        font_resolver.lock().unwrap().select_fallback(
                            c,
                            exclude_fonts,
                            db,
                        )
                    }),
                },
                image_href_resolver: usvg::ImageHrefResolver {
                    resolve_data: usvg::ImageHrefResolver::default_data_resolver(),
                    resolve_string: Box::new(|href, _opts| {
                        image_resolver.lock().unwrap().load(href)
                    }),
                },
                ..base_options()
            },
        )
        .map_err(format_usvg_error)?;
        if let Some(err) = image_resolver.into_inner().unwrap().error {
            return Err(err);
        }
        let font_hash = font_resolver.into_inner().unwrap().finish();
        Ok(Self(Arc::new(Repr { data, size: tree_size(&tree), font_hash, tree })))
    }

    /// The raw image data.
    pub fn data(&self) -> &Bytes {
        &self.0.data
    }

    /// The SVG's width in pixels.
    pub fn width(&self) -> f64 {
        self.0.size.x
    }

    /// The SVG's height in pixels.
    pub fn height(&self) -> f64 {
        self.0.size.y
    }

    /// Accesses the usvg tree.
    pub fn tree(&self) -> &usvg::Tree {
        &self.0.tree
    }
}

impl Hash for Repr {
    fn hash<H: Hasher>(&self, state: &mut H) {
        // An SVG might contain fonts, which must be incorporated into the hash.
        // We can't hash a usvg tree directly, but the raw SVG data + a hash of
        // all used fonts gives us something similar.