use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ExtractMode {
Markdown,
Article,
Text,
Selector,
Metadata,
Links,
Jsonpath,
Feed,
#[serde(rename = "llm_txt")]
LlmTxt,
}
impl ExtractMode {
pub const ALL_NAMES: &'static [&'static str] = &[
"markdown", "article", "text", "selector", "metadata", "links", "jsonpath", "feed",
"llm_txt",
];
pub fn parse(s: &str) -> Option<Self> {
match s {
"markdown" => Some(Self::Markdown),
"article" => Some(Self::Article),
"text" => Some(Self::Text),
"selector" => Some(Self::Selector),
"metadata" => Some(Self::Metadata),
"links" => Some(Self::Links),
"jsonpath" => Some(Self::Jsonpath),
"feed" => Some(Self::Feed),
"llm_txt" => Some(Self::LlmTxt),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Markdown => "markdown",
Self::Article => "article",
Self::Text => "text",
Self::Selector => "selector",
Self::Metadata => "metadata",
Self::Links => "links",
Self::Jsonpath => "jsonpath",
Self::Feed => "feed",
Self::LlmTxt => "llm_txt",
}
}
pub fn required_feature(&self) -> Option<&'static str> {
match self {
Self::Markdown => Some("fetch-markdown"),
Self::Article => Some("fetch-article"),
Self::Text | Self::Selector | Self::Metadata | Self::Links => Some("fetch-html"),
Self::Feed => Some("fetch-feed"),
Self::Jsonpath | Self::LlmTxt => None,
}
}
}
impl std::fmt::Display for ExtractMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ResponseMode {
Full,
Binary,
}
impl ResponseMode {
pub const ALL_NAMES: &'static [&'static str] = &["full", "binary"];
pub fn parse(s: &str) -> Option<Self> {
match s {
"full" => Some(Self::Full),
"binary" => Some(Self::Binary),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Full => "full",
Self::Binary => "binary",
}
}
}
impl std::fmt::Display for ResponseMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extract_mode_parse_all() {
for name in ExtractMode::ALL_NAMES {
assert!(
ExtractMode::parse(name).is_some(),
"failed to parse '{name}'"
);
}
assert!(ExtractMode::parse("unknown").is_none());
assert!(ExtractMode::parse("").is_none());
}
#[test]
fn extract_mode_roundtrip_str() {
for name in ExtractMode::ALL_NAMES {
let mode = ExtractMode::parse(name).unwrap();
assert_eq!(mode.as_str(), *name);
assert_eq!(mode.to_string(), *name);
}
}
#[test]
fn extract_mode_serde_roundtrip() {
for name in ExtractMode::ALL_NAMES {
let yaml = format!("\"{}\"", name);
let mode: ExtractMode = serde_json::from_str(&yaml).unwrap();
assert_eq!(mode, ExtractMode::parse(name).unwrap());
let back = serde_json::to_string(&mode).unwrap();
assert_eq!(back, yaml);
}
}
#[test]
fn extract_mode_llm_txt_serde() {
let mode: ExtractMode = serde_json::from_str("\"llm_txt\"").unwrap();
assert_eq!(mode, ExtractMode::LlmTxt);
assert_eq!(serde_json::to_string(&mode).unwrap(), "\"llm_txt\"");
}
#[test]
fn response_mode_parse_all() {
for name in ResponseMode::ALL_NAMES {
assert!(
ResponseMode::parse(name).is_some(),
"failed to parse '{name}'"
);
}
assert!(ResponseMode::parse("stream").is_none());
assert!(ResponseMode::parse("").is_none());
}
#[test]
fn response_mode_serde_roundtrip() {
for name in ResponseMode::ALL_NAMES {
let yaml = format!("\"{}\"", name);
let mode: ResponseMode = serde_json::from_str(&yaml).unwrap();
assert_eq!(mode, ResponseMode::parse(name).unwrap());
}
}
#[test]
fn extract_mode_required_features() {
assert_eq!(
ExtractMode::Markdown.required_feature(),
Some("fetch-markdown")
);
assert_eq!(
ExtractMode::Article.required_feature(),
Some("fetch-article")
);
assert_eq!(ExtractMode::Text.required_feature(), Some("fetch-html"));
assert_eq!(ExtractMode::Feed.required_feature(), Some("fetch-feed"));
assert_eq!(ExtractMode::Jsonpath.required_feature(), None);
assert_eq!(ExtractMode::LlmTxt.required_feature(), None);
}
}