use tokenizer::{TokenizerOpts, Tokenizer, TokenSink};
use tree_builder::{TreeBuilderOpts, TreeBuilder, TreeSink};
use std::option;
use std::default::Default;
use string_cache::{Atom, QualName};
use tendril::StrTendril;
pub fn one_input<T>(x: T) -> option::IntoIter<T> {
Some(x).into_iter()
}
pub fn tokenize_to<Sink, It>(sink: Sink, input: It, opts: TokenizerOpts) -> Sink
where Sink: TokenSink,
It: Iterator<Item=StrTendril>,
{
let mut tok = Tokenizer::new(sink, opts);
for s in input {
tok.feed(s);
}
tok.end();
tok.unwrap()
}
#[derive(Clone, Default)]
pub struct ParseOpts {
pub tokenizer: TokenizerOpts,
pub tree_builder: TreeBuilderOpts,
}
pub fn parse_to<Sink, It>(sink: Sink, input: It, opts: ParseOpts) -> Sink
where Sink: TreeSink,
It: Iterator<Item=StrTendril>,
{
let tb = TreeBuilder::new(sink, opts.tree_builder);
let mut tok = Tokenizer::new(tb, opts.tokenizer);
for s in input {
tok.feed(s);
}
tok.end();
tok.unwrap().unwrap()
}
pub fn parse_fragment_to<Sink, It>(sink: Sink,
input: It,
context: Atom,
opts: ParseOpts) -> Sink
where Sink: TreeSink,
It: Iterator<Item=StrTendril>
{
let mut sink = sink;
let context_elem = sink.create_element(QualName::new(ns!(HTML), context), vec!());
let tb = TreeBuilder::new_for_fragment(sink, context_elem, None, opts.tree_builder);
let tok_opts = TokenizerOpts {
initial_state: Some(tb.tokenizer_state_for_context_elem()),
.. opts.tokenizer
};
let mut tok = Tokenizer::new(tb, tok_opts);
for s in input {
tok.feed(s);
}
tok.end();
tok.unwrap().unwrap()
}
pub trait ParseResult {
type Sink: TreeSink + Default;
fn get_result(sink: Self::Sink) -> Self;
}
pub fn parse<Output, It>(input: It, opts: ParseOpts) -> Output
where Output: ParseResult,
It: Iterator<Item=StrTendril>,
{
let sink = parse_to(Default::default(), input, opts);
ParseResult::get_result(sink)
}
pub fn parse_fragment<Output, It>(input: It, context: Atom, opts: ParseOpts) -> Output
where Output: ParseResult,
It: Iterator<Item=StrTendril>,
{
let sink = parse_fragment_to(Default::default(), input, context, opts);
ParseResult::get_result(sink)
}