Repository: servo/servo
File: components/fonts/font_context.rs (Rust)

Code before:
                        let template = FontTemplate::new_for_local_web_font(
                            local_template.clone(),
                            &state.css_font_face_descriptors,
                            state.initiator.stylesheet().cloned(),
                        )
                        .ok()?;
                        Some(template)
                    })
                {
                    state.handle_web_font_load_success(new_template);
                } else {
                    this.process_next_web_font_source(state);
                }
            },
        }
    }
}

pub(crate) type ScriptWebFontLoadFinishedCallback =
    Box<dyn FnOnce(LowercaseFontFamilyName, Option<FontTemplate>) + Send>;

pub(crate) enum WebFontLoadInitiator {
    Stylesheet(
        Box<FontFaceRuleInitiator>,
        StylesheetWebFontLoadFinishedCallback,
    ),
    Script(ScriptWebFontLoadFinishedCallback),
}

impl WebFontLoadInitiator {
    pub(crate) fn stylesheet(&self) -> Option<&FontFaceRuleInitiator> {
        match self {
            Self::Stylesheet(font_face_rule, _) => Some(font_face_rule),
            Self::Script(_) => None,
        }
    }
}

struct RemoteWebFontDownloader {
    state: Option<WebFontDownloadState>,
    url: ServoArc<Url>,
    web_font_family_name: LowercaseFontFamilyName,
    response_valid: bool,
    response_data: Vec<u8>,
}

enum DownloaderResponseResult {
    InProcess,
    Finished,
    Failure,
}

Review comment (suggestion):
I think we shouldn't add an intermediate type here and just keep these separate for clarity:


```suggestion
    Stylesheet {
        stylesheet: DocumentStyleSheet,
        font_face_rule: FontFaceRule,
        callback: StylesheetWebFontLoadFinishedCallback,
    },
```

Code after:
                    .flatten()
                    .and_then(|local_template| {
                        let template = FontTemplate::new_for_local_web_font(
                            local_template.clone(),
                            &state.css_font_face_descriptors,
                            state.initiator.stylesheet().cloned(),
                            state.initiator.font_face_rule().cloned(),
                        )
                        .ok()?;
                        Some(template)
                    })
                {
                    state.handle_web_font_load_success(new_template);
                } else {
                    this.process_next_web_font_source(state);
                }
            },
        }
    }
}

pub(crate) type ScriptWebFontLoadFinishedCallback =
    Box<dyn FnOnce(LowercaseFontFamilyName, Option<FontTemplate>) + Send>;

pub(crate) struct FontFaceRuleInitiator {
    stylesheet: DocumentStyleSheet,
    font_face_rule: FontFaceRule,
    callback: StylesheetWebFontLoadFinishedCallback,
}

pub(crate) enum WebFontLoadInitiator {
    Stylesheet(Box<FontFaceRuleInitiator>),
    Script(ScriptWebFontLoadFinishedCallback),
}

impl WebFontLoadInitiator {
    pub(crate) fn stylesheet(&self) -> Option<&DocumentStyleSheet> {
        match self {
            Self::Stylesheet(initiator) => Some(&initiator.stylesheet),
            Self::Script(_) => None,
        }
    }

    pub(crate) fn font_face_rule(&self) -> Option<&FontFaceRule> {
        match self {
            Self::Stylesheet(initiator) => Some(&initiator.font_face_rule),
            Self::Script(_) => None,
        }
    }
}