parse_book_source/source/
rule.rs1use super::clean::CleanStep;
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
10#[serde(rename_all = "lowercase")]
11#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
12pub enum Via {
13 #[default]
14 Css,
15 Xpath,
16 Json,
17 Regex,
18 Raw,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
24#[serde(untagged)]
25#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
26pub enum Extract {
27 Op(ExtractOp),
28 Attr { attr: String },
29}
30
31impl Default for Extract {
32 fn default() -> Self {
33 Extract::Op(ExtractOp::Text)
34 }
35}
36
37#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
39#[serde(rename_all = "camelCase")]
40#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
41pub enum ExtractOp {
42 #[default]
43 Text,
44 OwnText,
45 Html,
46 InnerHtml,
47 OuterHtml,
48}
49
50#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
52#[serde(rename_all = "camelCase")]
53#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
54pub struct LeafRule {
55 #[serde(default)]
56 pub via: Via,
57 #[serde(default, skip_serializing_if = "Option::is_none")]
58 pub select: Option<String>,
59 #[serde(default, skip_serializing_if = "Option::is_none")]
60 pub index: Option<i64>,
61 #[serde(default)]
62 pub extract: Extract,
63 #[serde(default, skip_serializing_if = "Vec::is_empty")]
64 pub clean: Vec<CleanStep>,
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
71#[serde(untagged)]
72#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
73pub enum Rule {
74 FirstOf {
76 #[serde(rename = "firstOf")]
77 first_of: Vec<Rule>,
78 },
79 Concat {
81 concat: Vec<Rule>,
82 #[serde(default)]
83 join: String,
84 },
85 Literal { literal: String },
87 Template { template: String },
89 Js { js: String },
93 Leaf(LeafRule),
95}
96
97impl Rule {
98 pub fn primary_via(&self) -> Option<Via> {
102 match self {
103 Rule::Leaf(l) => Some(l.via),
104 Rule::FirstOf { first_of } => first_of.first().and_then(Rule::primary_via),
105 Rule::Concat { concat, .. } => concat.first().and_then(Rule::primary_via),
106 Rule::Literal { .. } | Rule::Template { .. } | Rule::Js { .. } => None,
107 }
108 }
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
113#[serde(untagged)]
114#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
115pub enum UrlOrRule {
116 Str(String),
117 Rule(Box<Rule>),
118}