Skip to content

Commit

Permalink
token_parser: unify parsing and serialization
Browse files Browse the repository at this point in the history
This reduces the number of things we have to update in our token parser
and serializer. For payloads, we we have to handle the payload cases
different, but we now have a structure that can deal with that
efficiently.

Signed-off-by: William Casarin <[email protected]>
  • Loading branch information
jb55 committed Jan 5, 2025
1 parent 631674c commit 6a76e67
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 43 deletions.
1 change: 1 addition & 0 deletions crates/notedeck_columns/src/storage/token_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ pub trait TokenSerializable: Sized {
/// Return a list of serialization plans for a type. We do this for
/// type safety and assume constructing these types are lightweight
fn parse<'a>(parser: &mut TokenParser<'a>) -> Result<Self, ParseError<'a>>;
fn serialize(&self, write_token: fn(&str) -> Result<(), std::io::Error>) -> Result<(), std::io::Error>;
}

#[cfg(test)]
Expand Down
90 changes: 47 additions & 43 deletions crates/notedeck_columns/src/ui/add_column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,47 @@ pub enum AddColumnRoute {
ExternalIndividual,
}

// Parser for the common case without any payloads
fn parse_column_route<'a>(
parser: &mut TokenParser<'a>,
route: AddColumnRoute,
) -> Result<AddColumnRoute, ParseError<'a>> {
parser.parse_all(|p| {
for token in route.tokens() {
p.parse_token(token)?;
}
Ok(route)
})
}

impl AddColumnRoute {
/// Route tokens use in both serialization and deserialization
fn tokens(&self) -> &'static [&'static str] {
match self {
Self::Base => &[],
Self::UndecidedNotification => &["notification_selection"],
Self::ExternalNotification => &["external_notif_selection"],
Self::UndecidedIndividual => &["individual_selection"],
Self::ExternalIndividual => &["external_individual_selection"],
Self::Hashtag => &["hashtag"],
Self::Algo(AddAlgoRoute::Base) => &["algo_selection"],
Self::Algo(AddAlgoRoute::LastPerPubkey) => &["algo_selection", "last_per_pubkey"],
// NOTE!!! When adding to this, update the parser for TokenSerializable below
}
}
}

impl TokenSerializable for AddColumnRoute {
fn serialize(
&self,
write_token: fn(&str) -> Result<(), std::io::Error>,
) -> Result<(), std::io::Error> {
for token in self.tokens() {
write_token(token)?;
}
Ok(())
}

fn parse<'a>(parser: &mut TokenParser<'a>) -> Result<Self, ParseError<'a>> {
// all start with column
parser.parse_token("column")?;
Expand All @@ -93,49 +133,13 @@ impl TokenSerializable for AddColumnRoute {
TokenParser::alt(
parser,
&[
|p| {
p.parse_all(|p| {
p.parse_token("external_notif_selection")?;
Ok(AddColumnRoute::UndecidedNotification)
})
},
|p| {
p.parse_all(|p| {
p.parse_token("external_notif_selection")?;
Ok(AddColumnRoute::ExternalNotification)
})
},
|p| {
p.parse_all(|p| {
p.parse_token("hashtag_selection")?;
Ok(AddColumnRoute::Hashtag)
})
},
|p| {
p.parse_all(|p| {
p.parse_token("algo_selection")?;
Ok(AddColumnRoute::Algo(AddAlgoRoute::Base))
})
},
|p| {
p.parse_all(|p| {
p.parse_token("algo_selection")?;
p.parse_token("last_per_pubkey")?;
Ok(AddColumnRoute::Algo(AddAlgoRoute::LastPerPubkey))
})
},
|p| {
p.parse_all(|p| {
p.parse_token("individual_selection")?;
Ok(AddColumnRoute::UndecidedIndividual)
})
},
|p| {
p.parse_all(|p| {
p.parse_token("external_individual_selection")?;
Ok(AddColumnRoute::ExternalIndividual)
})
},
|p| parse_column_route(p, AddColumnRoute::UndecidedNotification),
|p| parse_column_route(p, AddColumnRoute::ExternalNotification),
|p| parse_column_route(p, AddColumnRoute::UndecidedIndividual),
|p| parse_column_route(p, AddColumnRoute::ExternalIndividual),
|p| parse_column_route(p, AddColumnRoute::Hashtag),
|p| parse_column_route(p, AddColumnRoute::Algo(AddAlgoRoute::Base)),
|p| parse_column_route(p, AddColumnRoute::Algo(AddAlgoRoute::LastPerPubkey)),
],
)
}
Expand Down

0 comments on commit 6a76e67

Please sign in to comment.