Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
3700ece
parser: bump edition to 2024
ada4a Sep 13, 2025
d16cbc8
unused/elidable lifetimes
ada4a Sep 14, 2025
14fd02d
redundant refs/derefs
ada4a Sep 14, 2025
9fa7b29
clippy::uninlined_format_args
ada4a Sep 14, 2025
cbb55d1
clippy::if_not_else
ada4a Sep 14, 2025
7081355
clippy::needless_return
ada4a Sep 14, 2025
aad6bc9
explicit iterator loops
ada4a Sep 14, 2025
c0162cb
clippy::useless_conversion
ada4a Sep 16, 2025
b458e55
simplify thanks to the previous commit
ada4a Sep 16, 2025
f3e4f50
simplify `match`es
ada4a Sep 13, 2025
57837a8
use `std::iter::zip`
ada4a Sep 15, 2025
2bde9ff
clippy::inefficient_to_string
ada4a Sep 15, 2025
1495532
clippy::ignored_unit_patterns
ada4a Sep 15, 2025
250d55f
derive `Default` for `IssueLinksCheckCommitsConfig`
ada4a Sep 15, 2025
c8502a2
use more idiomatic iterator/`Option` adaptors
ada4a Sep 15, 2025
3b23d19
clean-up consts
ada4a Sep 15, 2025
c4ac3ec
use `let-else`
ada4a Sep 15, 2025
985f17b
clippy::cast_lossless
ada4a Sep 15, 2025
69fdfd4
documentation lints
ada4a Sep 15, 2025
668b872
reborrow instead of slicing
ada4a Sep 15, 2025
63aa79c
add/remove semicolons
ada4a Sep 15, 2025
a7e2a2e
clippy::write_with_newline
ada4a Sep 15, 2025
7fcd5cc
clippy::manual_string_new
ada4a Sep 15, 2025
d35ecc2
clippy::single_char_pattern
ada4a Sep 15, 2025
69510c0
clippy::implicit_clone
ada4a Sep 15, 2025
c61994a
get `command` without unwrapping
ada4a Sep 15, 2025
d68cfea
`write!` _inside_ `match`
ada4a Sep 15, 2025
e3144e6
clippy::unneded_struct_pattern
ada4a Sep 15, 2025
cae5dc0
clippy::manual_strip
ada4a Sep 15, 2025
71ac3c8
clippy::manual_assert
ada4a Sep 15, 2025
b4732de
needless `into_iter`
ada4a Sep 14, 2025
eb647df
clippy::legacy_numeric_constants
ada4a Sep 14, 2025
1f7197e
clippy::inconsistent_struct_constructor
ada4a Sep 14, 2025
3d806ad
clippy::redundant_closure_for_method_calls
ada4a Sep 14, 2025
1129636
clippy::manual_is_variant_and
ada4a Sep 14, 2025
0635365
clippy::needless_raw_string_hashes
ada4a Sep 14, 2025
091428e
clippy::question_mark
ada4a Sep 14, 2025
12f554b
construct `HashMap` from array
ada4a Sep 14, 2025
6798e50
clippy::collapsible{,_else}_if
ada4a Sep 14, 2025
18abb46
use `Result::ok_or` for trying out multiple things
ada4a Sep 14, 2025
d388132
use `as_deref` to avoid allocating a String
ada4a Sep 15, 2025
f98014d
`RustcFormat::store_version`: take params by reference
ada4a Sep 14, 2025
44af4a1
`config`: introduce `MaybeConfig` type alias
ada4a Sep 14, 2025
d43fb74
avoid eager/useless `format!`s
ada4a Sep 14, 2025
d0223be
replace `std::iter::once(_)` with `[_]`
ada4a Sep 14, 2025
d719e8b
use `Itertools::format`
ada4a Sep 14, 2025
e206d2c
replace `.ok_or_else(|| anyhow::anyhow!` with `.context(`
ada4a Sep 14, 2025
b5bd250
don't destructure tuple for comparison
ada4a Sep 14, 2025
c582664
`expect` some lints
ada4a Sep 16, 2025
1fa3f17
clippy::field_reassign_with_default
ada4a Sep 16, 2025
bdc91da
clippy::vec_init_then_push
ada4a Sep 16, 2025
93d669a
avoid `clippy::partialeq_to_none`
ada4a Sep 16, 2025
ba30132
clippy::manual_find
ada4a Sep 16, 2025
4d0226b
clippy::ptr_arg
ada4a Sep 16, 2025
3014ff3
deref `Label` to `&str` directly
ada4a Sep 16, 2025
289cd18
clippy::redundant_pattern_matching
ada4a Sep 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions github-graphql/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,17 +323,11 @@ pub mod project_items {

impl ProjectV2Item {
pub fn status(&self) -> Option<&str> {
let Some(ref status) = self.status else {
return None;
};
status.as_str()
self.status.as_ref()?.as_str()
}

pub fn date(&self) -> Option<Date> {
let Some(ref date) = self.date else {
return None;
};
date.as_date()
self.date.as_ref()?.as_date()
}
}

Expand Down
2 changes: 1 addition & 1 deletion parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "parser"
version = "0.1.0"
authors = ["Mark Rousskov <[email protected]>"]
edition = "2021"
edition = "2024"

[dependencies]
pulldown-cmark = "0.12.0"
Expand Down
17 changes: 8 additions & 9 deletions parser/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl<'a> Input<'a> {
pub fn new(input: &'a str, bot: Vec<&'a str>) -> Input<'a> {
let bots: Vec<_> = bot.iter().map(|bot| format!(r"(?:@{bot}\b)")).collect();
let bot_re = Regex::new(&format!(
r#"(?i)(?P<review>\br\?)|{bots}"#,
r"(?i)(?P<review>\br\?)|{bots}",
bots = bots.join("|")
))
.unwrap();
Expand Down Expand Up @@ -140,13 +140,12 @@ impl<'a> Input<'a> {
&original_tokenizer,
));

if success.len() > 1 {
panic!(
"succeeded parsing {:?} to multiple commands: {:?}",
&self.all[self.parsed..],
success
);
}
assert!(
success.len() <= 1,
"succeeded parsing {:?} to multiple commands: {:?}",
&self.all[self.parsed..],
success
);

let (mut tok, c) = success.pop()?;
// if we errored out while parsing the command do not move the input forwards
Expand Down Expand Up @@ -201,7 +200,7 @@ impl<'a> Iterator for Input<'a> {
}
}

impl<'a> Command<'a> {
impl Command<'_> {
pub fn is_ok(&self) -> bool {
match self {
Command::Relabel(r) => r.is_ok(),
Expand Down
18 changes: 9 additions & 9 deletions parser/src/command/assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ impl AssignCommand {
let mut toks = input.clone();
if let Some(Token::Word("claim")) = toks.peek_token()? {
toks.next_token()?;
if let Some(Token::Dot) | Some(Token::EndOfLine) = toks.peek_token()? {
if let Some(Token::Dot | Token::EndOfLine) = toks.peek_token()? {
toks.next_token()?;
*input = toks;
return Ok(Some(AssignCommand::Claim));
Ok(Some(AssignCommand::Claim))
} else {
return Err(toks.error(ParseError::ExpectedEnd));
Err(toks.error(ParseError::ExpectedEnd))
}
} else if let Some(Token::Word("assign")) = toks.peek_token()? {
toks.next_token()?;
Expand All @@ -63,22 +63,22 @@ impl AssignCommand {
username: user[1..].to_owned(),
}))
} else {
return Err(toks.error(ParseError::MentionUser));
Err(toks.error(ParseError::MentionUser))
}
} else {
return Err(toks.error(ParseError::NoUser));
Err(toks.error(ParseError::NoUser))
}
} else if let Some(Token::Word("release-assignment" | "unclaim")) = toks.peek_token()? {
toks.next_token()?;
if let Some(Token::Dot) | Some(Token::EndOfLine) = toks.peek_token()? {
if let Some(Token::Dot | Token::EndOfLine) = toks.peek_token()? {
toks.next_token()?;
*input = toks;
return Ok(Some(AssignCommand::ReleaseAssignment));
Ok(Some(AssignCommand::ReleaseAssignment))
} else {
return Err(toks.error(ParseError::ExpectedEnd));
Err(toks.error(ParseError::ExpectedEnd))
}
} else {
return Ok(None);
Ok(None)
}
}

Expand Down
10 changes: 5 additions & 5 deletions parser/src/command/concern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ impl ConcernCommand {
if let Some(Token::Word(mut action @ ("concern" | "resolve"))) = toks.peek_token()? {
toks.next_token()?;

if action == "concern" {
if let Some(Token::Word(sub_action @ "resolve")) = toks.peek_token()? {
toks.next_token()?;
action = sub_action;
}
if action == "concern"
&& let Some(Token::Word(sub_action @ "resolve")) = toks.peek_token()?
{
toks.next_token()?;
action = sub_action;
}

let title = toks.take_line()?.trim().to_string();
Expand Down
21 changes: 9 additions & 12 deletions parser/src/command/nominate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,26 +55,23 @@ impl NominateCommand {
let style = match toks.peek_token()? {
Some(Token::Word("beta-nominate")) => Style::Beta,
Some(Token::Word("nominate")) => Style::Decision,
Some(Token::Word("beta-accept")) => Style::BetaApprove,
Some(Token::Word("beta-approve")) => Style::BetaApprove,
Some(Token::Word("beta-accept" | "beta-approve")) => Style::BetaApprove,
None | Some(_) => return Ok(None),
};
toks.next_token()?;
let team = if style != Style::BetaApprove {
if let Some(Token::Word(team)) = toks.next_token()? {
team.to_owned()
} else {
return Err(toks.error(ParseError::NoTeam));
}
} else {
let team = if style == Style::BetaApprove {
String::new()
} else if let Some(Token::Word(team)) = toks.next_token()? {
team.to_owned()
} else {
return Err(toks.error(ParseError::NoTeam));
};
if let Some(Token::Dot) | Some(Token::EndOfLine) = toks.peek_token()? {
if let Some(Token::Dot | Token::EndOfLine) = toks.peek_token()? {
toks.next_token()?;
*input = toks;
return Ok(Some(NominateCommand { team, style }));
Ok(Some(NominateCommand { team, style }))
} else {
return Err(toks.error(ParseError::ExpectedEnd));
Err(toks.error(ParseError::ExpectedEnd))
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions parser/src/command/ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ impl PingCommand {
} else {
return Err(toks.error(ParseError::NoTeam));
};
if let Some(Token::Dot) | Some(Token::EndOfLine) = toks.peek_token()? {
if let Some(Token::Dot | Token::EndOfLine) = toks.peek_token()? {
toks.next_token()?;
*input = toks;
return Ok(Some(PingCommand { team }));
Ok(Some(PingCommand { team }))
} else {
return Err(toks.error(ParseError::ExpectedEnd));
Err(toks.error(ParseError::ExpectedEnd))
}
} else {
return Ok(None);
Ok(None)
}
}
}
Expand Down
21 changes: 9 additions & 12 deletions parser/src/command/relabel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ impl Label {
}

impl std::ops::Deref for Label {
type Target = String;
fn deref(&self) -> &String {
&self.0
type Target = str;
fn deref(&self) -> &str {
self.0.as_str()
}
}

Expand All @@ -68,13 +68,13 @@ impl LabelDelta {
return Err(input.error(ParseError::ExpectedLabelDelta));
}
};
if delta.starts_with('+') {
if let Some(label) = delta.strip_prefix('+') {
Ok(LabelDelta::Add(
Label::parse(&delta[1..]).map_err(|e| input.error(e))?,
Label::parse(label).map_err(|e| input.error(e))?,
))
} else if delta.starts_with('-') {
} else if let Some(label) = delta.strip_prefix('-') {
Ok(LabelDelta::Remove(
Label::parse(&delta[1..]).map_err(|e| input.error(e))?,
Label::parse(label).map_err(|e| input.error(e))?,
))
} else {
Ok(LabelDelta::Add(
Expand All @@ -85,8 +85,7 @@ impl LabelDelta {

pub fn label(&self) -> &Label {
match self {
LabelDelta::Add(l) => l,
LabelDelta::Remove(l) => l,
LabelDelta::Add(l) | LabelDelta::Remove(l) => l,
}
}
}
Expand Down Expand Up @@ -129,9 +128,7 @@ impl RelabelCommand {
toks.eat_token(Token::Comma)?;
toks.eat_token(Token::Word("and"))?;

if let Some(Token::Semi) | Some(Token::Dot) | Some(Token::EndOfLine) =
toks.peek_token()?
{
if let Some(Token::Semi | Token::Dot | Token::EndOfLine) = toks.peek_token()? {
toks.next_token()?;
*input = toks;
return Ok(Some(RelabelCommand(deltas)));
Expand Down
20 changes: 10 additions & 10 deletions parser/src/command/shortcut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ impl fmt::Display for ParseError {

impl ShortcutCommand {
pub fn parse<'a>(input: &mut Tokenizer<'a>) -> Result<Option<Self>, Error<'a>> {
let mut shortcuts = HashMap::new();
shortcuts.insert("ready", ShortcutCommand::Ready);
shortcuts.insert("review", ShortcutCommand::Ready);
shortcuts.insert("reviewer", ShortcutCommand::Ready);
shortcuts.insert("author", ShortcutCommand::Author);
shortcuts.insert("blocked", ShortcutCommand::Blocked);
let shortcuts = HashMap::from([
("ready", ShortcutCommand::Ready),
("review", ShortcutCommand::Ready),
("reviewer", ShortcutCommand::Ready),
("author", ShortcutCommand::Author),
("blocked", ShortcutCommand::Blocked),
]);

let mut toks = input.clone();
if let Some(Token::Word(word)) = toks.peek_token()? {
if !shortcuts.contains_key(word) {
let Some(command) = shortcuts.get(word) else {
return Ok(None);
}
};
toks.next_token()?;
*input = toks;
let command = shortcuts.get(word).unwrap();
return Ok(Some(*command));
}
Ok(None)
Expand All @@ -57,7 +57,7 @@ impl ShortcutCommand {
#[cfg(test)]
fn parse(input: &str) -> Result<Option<ShortcutCommand>, Error<'_>> {
let mut toks = Tokenizer::new(input);
Ok(ShortcutCommand::parse(&mut toks)?)
ShortcutCommand::parse(&mut toks)
}

#[test]
Expand Down
8 changes: 4 additions & 4 deletions parser/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,25 @@ pub struct Error<'a> {
pub source: Box<dyn error::Error + Send>,
}

impl<'a> PartialEq for Error<'a> {
impl PartialEq for Error<'_> {
fn eq(&self, other: &Self) -> bool {
self.input == other.input && self.position == other.position
}
}

impl<'a> error::Error for Error<'a> {
impl error::Error for Error<'_> {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(&*self.source)
}
}

impl<'a> Error<'a> {
impl Error<'_> {
pub fn position(&self) -> usize {
self.position
}
}

impl<'a> fmt::Display for Error<'a> {
impl fmt::Display for Error<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let space = 10;
let end = std::cmp::min(self.input.len(), self.position + space);
Expand Down
8 changes: 4 additions & 4 deletions parser/src/ignore_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl IgnoreBlocks {
macro_rules! ignore_till_end {
($p:pat) => {
let start = range.start;
while let Some((event, range)) = parser.next() {
for (event, range) in parser.by_ref() {
if let Event::End($p) = event {
ignore.push(start..range.end);
break;
Expand All @@ -28,15 +28,15 @@ impl IgnoreBlocks {
ignore_till_end!(TagEnd::CodeBlock);
}
Event::Start(Tag::Link { .. }) => {
ignore_till_end!(TagEnd::Link { .. });
ignore_till_end!(TagEnd::Link);
}
Event::Start(Tag::Image { .. }) => {
ignore_till_end!(TagEnd::Image { .. });
ignore_till_end!(TagEnd::Image);
}
Event::Start(Tag::BlockQuote(_)) => {
let start = range.start;
let mut count = 1;
while let Some((event, range)) = parser.next() {
for (event, range) in parser.by_ref() {
if let Event::Start(Tag::BlockQuote(_)) = event {
count += 1;
} else if let Event::End(TagEnd::BlockQuote(_)) = event {
Expand Down
16 changes: 7 additions & 9 deletions parser/src/mentions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@ pub fn get_mentions(input: &str) -> Vec<&str> {

let mut mentions = Vec::new();
for (idx, _) in input.match_indices('@') {
if let Some(previous) = input[..idx].chars().next_back() {
// A github username must stand apart from other text.
//
// Oddly enough, english letters do not work, but letters outside
// ASCII do work as separators; for now just go with this limited
// list.
if let 'a'..='z' | 'A'..='Z' | '0'..='9' = previous {
continue;
}
// A github username must stand apart from other text.
//
// Oddly enough, english letters do not work, but letters outside
// ASCII do work as separators; for now just go with this limited
// list.
if let Some('a'..='z' | 'A'..='Z' | '0'..='9') = input[..idx].chars().next_back() {
continue;
}
let mut saw_slash = false;
let username_end = input
Expand Down
Loading
Loading