Skip to content

Instantly share code, notes, and snippets.

@nikomatsakis
Created June 7, 2017 14:29
Show Gist options
  • Save nikomatsakis/e14a8d3be5af178558cc9692637de3e1 to your computer and use it in GitHub Desktop.
Save nikomatsakis/e14a8d3be5af178558cc9692637de3e1 to your computer and use it in GitHub Desktop.
#![allow(dead_code)]
struct Tokenizer<'t>(&'t str);
struct ParserInput<'t>(Tokenizer<'t>);
struct Parser<'i: 't, 't> {
tokenizer: &'t mut ParserInput<'i>,
}
enum ParseError<'i, E> {
Foo(&'i str),
Custom(E),
}
impl<'i: 't, 't> Parser<'i, 't> {
fn parse_comma_separated<T, F, E>(&mut self, parse_one: F) -> Result<T, ParseError<'i, E>>
where F: for<'ttt> FnMut(&mut Parser<'i, 'ttt>) -> Result<T, ParseError<'i, E>> {
self.parse_until_before(parse_one)
}
fn parse_entirely<T, F, E>(&mut self, parse: F) -> Result<T, ParseError<'i, E>>
where F: FnOnce(&mut Parser<'i, 't>) -> Result<T, ParseError<'i, E>> {
parse(self)
}
}
trait ParseUntilBefore<'i> {
fn parse_until_before<T, F, E>(&mut self, parse: F) -> Result<T, ParseError<'i, E>>
where F: for<'ttt> FnOnce(&mut Parser<'i, 'ttt>) -> Result<T, ParseError<'i, E>>;
}
impl<'i, 't> ParseUntilBefore<'i> for Parser<'i, 't> {
fn parse_until_before<T, F, E>(&mut self, parse: F) -> Result<T, ParseError<'i, E>>
where F: for<'ttt> FnOnce(&mut Parser<'i, 'ttt>) -> Result<T, ParseError<'i, E>>
{
let result;
// Introduce a new scope to limit duration of nested_parser’s borrow
{
let mut delimited_parser = Parser {
tokenizer: self.tokenizer,
};
result = delimited_parser.parse_entirely(parse);
}
result
}
}
struct DeclarationListParser<'i: 't, 't: 'a, 'a> {
input: &'a mut Parser<'i, 't>,
}
impl<'i: 't, 't: 'a, 'a> DeclarationListParser<'i, 't, 'a> {
fn foo(&mut self) {
let _: Result<(), ParseError<()>> = self.input.parse_until_before(|_input| Ok(()));
}
}
trait Foo {
type Error;
}
enum SelectorError<'i> {
Foo(&'i str),
}
fn parse<'i, 't>(input: &mut Parser<'i, 't>)
-> Result<(), ParseError<'i, SelectorError<'i>>>
{
input.parse_comma_separated(|input| parse_selector(input))
}
fn parse_selector<'i, 't>(_input: &mut Parser<'i, 't>)
-> Result<(), ParseError<'i, SelectorError<'i>>>
{
Ok(())
}
trait QualifiedRuleParserResult<'i> {
type Prelude;
type Error;
}
trait QualifiedRuleParser<'i, 't>: QualifiedRuleParserResult<'i> {
fn parse_prelude(&mut self, _input: &mut Parser<'i, 't>)
-> Result<Self::Prelude, ParseError<'i, Self::Error>>;
}
impl<'i> QualifiedRuleParserResult<'i> for () {
type Prelude = ();
type Error = SelectorError<'i>;
}
impl<'i, 't> QualifiedRuleParser<'i, 't> for () {
fn parse_prelude(&mut self, input: &mut Parser<'i, 't>)
-> Result<Self::Prelude, ParseError<'i, Self::Error>> {
Err(ParseError::Foo(""))
}
}
fn parse_qualified_rule<'i: 't, 't, P, E>(input: &mut Parser<'i, 't>, parser: &mut P)
-> Result<P::Prelude, ParseError<'i, E>>
where P: for<'ttt> QualifiedRuleParser<'i, 'ttt, Error = E>,
P: QualifiedRuleParserResult<'i, Error = E>,
{
<Parser<'i, 't> as ParseUntilBefore<'i>>::parse_until_before(input, |input| {
parser.parse_prelude(input)
})
}
fn main() {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment