1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use crate::from_html::{ExtractionType, StructErrorCause, StructFieldError};
use crate::mapper::Mapper;
use crate::transformer::Transformer;
use crate::Error;
use crate::{CssSelector, FromHtml, HtmlNode};
pub fn select<N>(source: &N, selector: &'static str) -> Vec<N>
where
N: HtmlNode,
{
let selector = N::Selector::parse(selector)
.unwrap();
source.select(&selector)
}
pub fn try_transform_and_map<N, T, M, S>(
source: S,
args: &T::Args,
selector: Option<&'static str>,
field_name: &'static str,
) -> Result<M, Box<dyn Error>>
where
N: HtmlNode,
T: FromHtml,
M: Mapper<T>,
S: Transformer<M::Structure<N>>,
{
source
.try_transform()
.map_err(StructErrorCause::StructureUnmatched)
.and_then(|s| M::try_map(s, args).map_err(StructErrorCause::ParseError))
.map_err(|e| StructFieldError {
field_name: field_name.to_string(),
selector: selector.map(|a| a.to_string()),
error: e,
})
.map_err(|e| Box::new(e) as Box<dyn Error>)
}
pub fn default_argument<T>() -> T
where
T: DefaultArg,
{
DefaultArg::default()
}
pub trait DefaultArg {
fn default() -> Self;
}
impl DefaultArg for () {
fn default() -> Self {}
}
impl DefaultArg for ExtractionType {
fn default() -> Self {
ExtractionType::Text
}
}