-
Notifications
You must be signed in to change notification settings - Fork 476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add AttributeSet type #2419
base: master
Are you sure you want to change the base?
Add AttributeSet type #2419
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, this is a definite improvement. See comments!
@@ -69,17 +69,17 @@ impl<'run, 'src> Analyzer<'run, 'src> { | |||
} => { | |||
let mut doc_attr: Option<&str> = None; | |||
let mut groups = Vec::new(); | |||
for attribute in attributes { | |||
attributes.ensure_valid_attributes( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should keep the error checking in the else
below, otherwise the set of allowed attributes is in two places, here, where we call ensure_valid_attributes
, and below, in the if / else
statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we keep the error checking here, then we would have pretty similar error-generation code here and in the ensure_valid_attributes
method. I added ensure_valid_attributes
as a way of de-duplicating attribute error generation code. I modified the code below to add an unreachable
and hopefully make it clearer what's going on.
src/attribute.rs
Outdated
inner: BTreeSet<Attribute<'src>>, | ||
} | ||
|
||
impl<'src> Serialize for AttributeSet<'src> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid needing to write a custom a serialize implementation if we make the struct:
pub(crate) struct AttributeSet<'src>(BTreeSet<Attribute<'src>>);
I think in that case serde will serialize the struct as just the inner contents.
src/attribute.rs
Outdated
} | ||
} | ||
|
||
pub(crate) fn count(&self) -> usize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just call this len
, since that's what native collections use.
src/attribute.rs
Outdated
|
||
pub(crate) fn contains(&self, target: AttributeDiscriminant) -> bool { | ||
self.inner.iter().any(|attr| { | ||
let discriminant: AttributeDiscriminant = attr.into(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a fn discriminant(&self) -> AttributeDiscriminant { self.into() }
function to Attribute
, so we can avoid needing to use type inference to do the conversion.
src/attribute.rs
Outdated
self.inner.iter() | ||
} | ||
|
||
pub(crate) fn private(&self) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should avoid one-off helpers like this, unless they do something more complex, since doing attributes.contains(AttributeDiscriminant::Private)
isn't so bad.
src/parser.rs
Outdated
@@ -1128,7 +1115,8 @@ impl<'run, 'src> Parser<'run, 'src> { | |||
if attributes.is_empty() { | |||
Ok(None) | |||
} else { | |||
Ok(Some((token.unwrap(), attributes.into_keys().collect()))) | |||
let attribute_set = AttributeSet::from_iter(attributes.into_keys()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you do collect
here instead of from_iter
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure what code change you want to see here.
src/recipe.rs
Outdated
None | ||
} | ||
}); | ||
let extension = self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original version of this is actually better, since we don't duplicate which attribute we're looking for.
src/recipe.rs
Outdated
if let Attribute::Doc(doc) = attribute { | ||
return doc.as_ref().map(|s| s.cooked.as_ref()); | ||
} | ||
if let Some(Attribute::Doc(doc)) = self.attributes.get(AttributeDiscriminant::Doc) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of a weird one. This if let
will only match if both self.attributes.get
returns Some
, and the returned attribute is an Attribute::Doc
, if the code is correct, of course, both or neither will be the case.
I think a more scrupulous correct version would be:
if let Some(attribute) = self.attributes.get(AttributeDiscriminant::Doc) {
if let Some(Attribute::Doc(doc)) else {
unreachable!();
}
}
Although that's a little crazy, so I think maybe the original on the left is better.
src/recipe.rs
Outdated
@@ -479,7 +483,7 @@ impl<'src, D: Display> ColorDisplay for Recipe<'src, D> { | |||
writeln!(f, "# {doc}")?; | |||
} | |||
|
|||
for attribute in &self.attributes { | |||
for attribute in self.attributes.iter() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should implement IntoIterator
for &AttributeSet
so we can avoid needing to call .iter()
.
2434438
to
73a6f51
Compare
fe755a7
to
b647045
Compare
Replace the several places that directly use a
BTreeSet<Attribute>
with a wrapper data structureAttributeSet
, that provides some convenience methods for working with attributes.