// impl Parser for ()
// any(a, b), all(a, b), seq(a, b)
// repeat(a, 3.., g), repeat_while(f, a), repeat_until(f, a)
// let t: impl Parser = (
//    repeat(alnum(), 1..).fold(String::new(), |mut s, c| {s.push(c); s}),
//    repeat(ws(), ..).ignore(),
//    literal('=').ignore(),
//    repeat(ws(), ..).ignore(),
//    repeat(char(), ..).until(|c| c == '\n').fold(String::new(), |mut s, c| {s.push(c); s})
// );
// let vars = repeat(t, ..).map(|(key, _, _, _, value)| (key, value)).collect::<HashMap<_, _>>();
// u64, be_u64, le_u64 - ascii number digits that fit in u64, 8 bytes be int, 8 bytes le int
/*
char
u8
Fn(T) -> bool
TokenIter - an iterator of types

#[derive(Deserialize)]
struct Env {
    name: String,
    value: Vec<u8>,
}

let equals = '='.repeat(..);
repeat gives Iterator<Item=T>

Each call creates a Parser<T>
A repeat parser wraps a byte or char parser and returns an RepeatIter<Inner>: Iterator<Item=Inner::Output>>

let t: Parser<Vec<Env>> = (
    ((
        output(HashMap::<&'static str, serde_json::Value>::new),
        char::when(|c| !c.is_whitespace()).repeat(1..).set(|map, chars| map.insert("name", chars.collect::<String>().into()))
        char::when(char::is_ascii_whitespace).repeat(..),
        '=',
        char::is_whitespace.repeat(..),
        char::when_clone(char::is_whitespace)
        (|b: u8| b != b'\n').repeat(..).set(|map, bytes| map.insert("value", bytes.collect::<Vec<u8>>.into()),
        b'\n',
        char::any()
    )).map(|h| serde::deserialize::<Env>(h))
).repeat(..) -> Iterator<Item=Env>

struct EnvVar {
    name: String,
    value: String,
}

impl Parser for EnvVar {
    type State =
    fn parse(&mut self, &input, state: State) {
        (
            char::when(|c| *c != '=').repeat(1..).set(|chars| {name = chars.collect::<String>()};),
            '=',
            char::when(|c| *c != '\n').repeat(..).set(|chars| {value = chars.collect::<String>();}),
            '\n',
        ).parse(input, state)
    );

    }
}
let envvar = || {
    let mut name = String::new();
    let mut value = String::new();
    let lang = (
        char::when(|c| *c != '=').repeat(1..).set(|chars| {name = chars.collect::<String>()};),
        '=',
        char::when(|c| *c != '\n').repeat(..).set(|chars| {value = chars.collect::<String>();}),
        '\n',
    );
}

#[derive(Deserialize)]
#[serde(untagged)]
enum F {
    A(u32),
    B(String)
}

let f = (
    u32,  // a set of digits
    (|c: char| c != '\0').repeat(..)
).shortest().deserialize::<F>();

.optional() == .repeat(..1)

let e: ParseResult<Vec<Env>> = t.parse(input);

let vars = t.repeat(..).map(|(key, _, _, _, value, _)| (key, value)).collect::<HashMap<_, _>>();
let kw = ("fn".map(|s| Kw::Fn), "const".map(|s| Kw::Const), "struct".map(|s| Kw::Struct), "enum".map(|s| Kw::Enum)).shortest();
let ident = (
    char::when(char::is_ascii_alphabetic),
    char::when(char::is_ascii_alphanumeric).repeat(..)
).sequence();
match kw.parse(input) {
    NoMatch => {},
    Partial => {},
    Complete(Kw::Fn) => {
        (
            char::when_clone(char::is_whitespace).repeat(..).ignore(),  => "  ", ""
            ident().field("function_name"),
            '('
            (
                deserialize::<Param>((
                    (
                        "mut".key("mut").value(true),
                        char::when_clone(char::is_whitespace).repeat(1..)
                    ).optional(),
                    ident().key("name"), // key returns ("name", T),
                    char::when_clone(char::is_whitespace).repeat(..),
                    ':',
                    r#type().key("type"),
                    char::when_clone(char::is_whitespace).repeat(..),
                )).continuator(  // or separator if trailing , not permitted
                    ',',
                    char::when_clone(char::is_whitespace).repeat(..),
                ).terminator(
                    ')'
                )
            ).repeat(..).collect::<Vec<_>>().field("params"),
            char::when_clone(char::is_whitespace).repeat(..),
            (
                "=>",
                char::when_clone(char::is_whitespace).repeat(..),
                r#type.field("return_type"),
                char::when_clone(char::is_whitespace).repeat(..),
            ).optional(),
            '{',
    }
}
Special Cow type - functions return String or Bytes that reference buffer, but when buffer is
dropped, all Cow's are turned into owned. If another buffer is parsed then Cow is turned into owned.

parser is a closure that returns ParseState::Fail, ParseState::Partial, or ParseState::Complete<T>.

struct ParamBuilder {
    is_mut: bool,
    name: String,
    type: String,
}

impl Parse for ParamBuilder {
    type Complete = Parameter;
    fn parse(input: &[u8]) -> ParseState<Complete> {
        match self.state {
            is_mut(matched)
        }
    }
}
 */

ParseResult<State, Result>

NoMatch
Partial(parse_state: State) -- assume input is all read
Complete(result, input)

fn parse(&mut self, input: &[u8]) -> ParseResult

write(buf: &[u8]) -> Result<> {
    match self.state {
        Init => {
            ParsingFridge(ident())
        }
        ParsingFridge(ident) => {
            match ident.parse(input) {
                NoMatch => {

                }
                Partial => {
                    ParsingFridge(ident)
                    return Ok(buf.len());
                }
                Complete(input) => {
                    remain = input;
                    fridge = ident.to_string();
                    NextState
                }
            }
        }
    }
}

impl Parse for Ident {
    fn new() {
        self.parser = char().until(|c| !c.is_alnum());
    }
    fn parse(&mut self, input) -> ParseResult {
        match self.parser
        if self.first {
            self.parser = char().until(|c| !c.is_alnum());
            match self.parser.parse(input) {
                NoMatch {
                    return NoMatch;
                }
                Partial(state) => {
                    self.state = state
                    return Partial
                }
            }
        } else {
            char().
        }
    }
}

fn ident() -> Ident {
    Ident::new()
}


input.parse("w") -> ParseResult::Match("w", None)

let mut terminator_string = Arc::new(Mutex::new(String::new()));

let mut input = ...;
let mut state = None;

let key_parser = (
    '-'.times(5),
    "BEGIN ",
    (
        "PRIVATE KEY",
        "CERTIFICATE",
    ).any(),
    '-'.times(5),
    char::when(|c: char| c.is_ascii_alphanumeric || c == '_' || c == '/' || c.is_ascii_whitespace())
        .repeat(..)
        .filter(|c| !char.is_ascii_whitespace)
        .collect::<String>(),
    '='.repeat(..=2).count(),
    char::when(char::is_ascii_whitespace),
    '-'.times(5),
    "END ",
    (
        char::when(|c| c != '-').repeat(1..).collect::<String>(),
    ),
    '-'.times(5),
    '\n'
).seq().map(|t| (t[2], t[4], t[5], t[7])); -> (&'static str, &'static str, &'static str, String, &'static str, String, &'static str)

let (keytype, content) = loop {
    match key_parser.parse(input, state) {  -> (&'static str, KeyType, &'static str, String, &'static str, String, &'static str)
        ParseResult::NoMatch => {bail!()},
        ParseResult::Partial(new_state) => {
            input = ...
            state = new_state;
        }
        ParseResult::Match((type1, content, eq_cnt, type2)) => {
            for i in ..eq_cnt {
                content.push('=');
            }
            // RFC 7468 permits labels to differ, so this should not exist.
            if type1 != type2.as_str() {
                bail!();
            }
            match type1 {
                "PRIVATE KEY" => {
                    break (KeyType::PrivateKey, content.b64decode())
                }
                "CERTIFICATE" => {
                    break (KeyType::Certificate, content.b64decode())
                }
                _ => {
                    bail!()
                }
            }
            break value;
        }
    }
}

let json_value = (
    char::when(char::is_ascii_whitespace).repeat(..),
    (
        &json_string,
        &json_number,
        &json_object,
        &json_array,
        "true",
        "false",
        "null",
    ).alt(),
    char::when(char::is_ascii_whitespace).repeat(..),
).seq();

let json_string = (
    '"',
    (
        (
            '\\',
            (
                '"',
                '\\',
                '/',
                ('b', 'f', 'n', 'r', 't').any().map(|bs| format!(""))
                'b'.replace('\b'),
                'f'.replace('\f'),
                'n'.replace('\n'),
                'r'.replace('\r'),
                't'.replace('\t'),
                (
                    'u',
                    char::when(char::is_ascii_hexdigit).times(4)
                ).seq().map(|(_, digits)| char::from_u32(...))
                )
            ).alaltt::<char>(),
        ).seq().map(|(_, c) c),
        char::when(|c| c != '\\' & c != '"'),
    ).alt::<char>().repeat(..)
    '"',
).seq().map(|(_, chars, _| chars.collect::<String>())


When a prefix provides a unique path that no other pattern will match we use unique to avodi scanning other alternatives:
(
    '0'.unique().map(std::iter::once),
    (
        '1'..='9', --> char
        char::when(char::is_ascii_digit).repeat(..),
    ).seq()
).one(),


let json_string = seq!(
    '-'.optional(),
    alt!(
        '0',
        seq!(
            alt!('1'..='9'),
            char::when(char::is_ascii_digit).repeat(..),
        ),
    ),
    opt!(
        '.',
        char::when(char::is_ascii_digit).repeat(1..),
    ),
    opt!(
        alt!('e', 'E'),
        ('-', '+').alt().optional(),
        char::when(char::is_ascii_digit).repeat(1..),
    )
);

input.parse(&json_value)

struct Input = Bytes

Output = Vec<(Bytes, is_utf8)>

Output::bytes() -> Iterator of u8
Output::chars() -> Iterator of char

On a tuple:
select returns a single Output from a tuple of patterns, specifically the first match that succeeds
any returns any single Output that passes - if a later alt passes before a previous alt is determined, then return later
seq returns a tuple of Output from a tuple of patterns, and the items must be in order
all returns a tuple of Output from a tuple of patterns, but the items may be in any order
chars() returns an iterator of all chars (&char) from an Output or tuple
bytes() returns an iterator of all bytes (&u8) from an Output or tuple
ignore() changes an Output to an empty Output
replace() changes an Output to a literal value (Cow)

let t = char::any();
(
    t,
    reverse5,
    take(5),
    alpha(5)
)

fn alpha(i: usize) -> impl Extract {
    char::when(char::is_alphabetic).times(i)
}

fn alpha(i: usize) -> Fn(&mut ByteStream) -> ParseResult<ByteStream, ByteStream> {
    move |input| char::when(char::is_alphabetic).times(i).extract(input, None)
}
