pendantic clippy lints
This commit is contained in:
parent
3ff68bfaf8
commit
0ce311a1eb
5 changed files with 42 additions and 48 deletions
|
@ -6,6 +6,8 @@ description = "A git-config file parser and editor from the gitoxide project"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
authors = ["Edward Shen <code@eddie.sh>"]
|
authors = ["Edward Shen <code@eddie.sh>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
keywords = ["git-config", "git", "config", "gitoxide"]
|
||||||
|
categories = ["config", "parser-implementations"]
|
||||||
exclude = ["fuzz/**/*", ".vscode/**/*"]
|
exclude = ["fuzz/**/*", ".vscode/**/*"]
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::parser::{parse_from_bytes, Event, ParsedSectionHeader, Parser, ParserError};
|
use crate::parser::{parse_from_bytes, Error, Event, ParsedSectionHeader, Parser};
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::error::Error;
|
|
||||||
use std::{borrow::Cow, fmt::Display};
|
use std::{borrow::Cow, fmt::Display};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord, Debug)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord, Debug)]
|
||||||
|
@ -30,7 +29,7 @@ impl Display for GitConfigError<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for GitConfigError<'_> {}
|
impl std::error::Error for GitConfigError<'_> {}
|
||||||
|
|
||||||
/// The section ID is a monotonically increasing ID used to refer to sections.
|
/// The section ID is a monotonically increasing ID used to refer to sections.
|
||||||
/// This value does not imply any ordering between sections, as new sections
|
/// This value does not imply any ordering between sections, as new sections
|
||||||
|
@ -51,6 +50,7 @@ enum LookupTreeNode<'a> {
|
||||||
Terminal(Vec<SectionId>),
|
Terminal(Vec<SectionId>),
|
||||||
NonTerminal(HashMap<Cow<'a, str>, Vec<SectionId>>),
|
NonTerminal(HashMap<Cow<'a, str>, Vec<SectionId>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// High level `git-config` reader and writer.
|
/// High level `git-config` reader and writer.
|
||||||
///
|
///
|
||||||
/// Internally, this uses various acceleration data structures to improve
|
/// Internally, this uses various acceleration data structures to improve
|
||||||
|
@ -537,7 +537,7 @@ impl<'a> GitConfig<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a str> for GitConfig<'a> {
|
impl<'a> TryFrom<&'a str> for GitConfig<'a> {
|
||||||
type Error = ParserError<'a>;
|
type Error = Error<'a>;
|
||||||
|
|
||||||
/// Convenience constructor. Attempts to parse the provided string into a
|
/// Convenience constructor. Attempts to parse the provided string into a
|
||||||
/// [`GitConfig`]. See [`parse_from_str`] for more information.
|
/// [`GitConfig`]. See [`parse_from_str`] for more information.
|
||||||
|
@ -549,7 +549,7 @@ impl<'a> TryFrom<&'a str> for GitConfig<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a [u8]> for GitConfig<'a> {
|
impl<'a> TryFrom<&'a [u8]> for GitConfig<'a> {
|
||||||
type Error = ParserError<'a>;
|
type Error = Error<'a>;
|
||||||
|
|
||||||
/// Convenience constructor. Attempts to parse the provided byte string into
|
/// Convenience constructor. Attempts to parse the provided byte string into
|
||||||
//// a [`GitConfig`]. See [`parse_from_bytes`] for more information.
|
//// a [`GitConfig`]. See [`parse_from_bytes`] for more information.
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
// #![deny(missing_docs)]
|
||||||
|
#![warn(clippy::pedantic, clippy::nursery, clippy::cargo)]
|
||||||
|
#![allow(clippy::must_use_candidate, clippy::shadow_unrelated)]
|
||||||
|
|
||||||
//! # git_config
|
//! # `git_config`
|
||||||
//!
|
//!
|
||||||
//! This crate is a high performance `git-config` file reader and writer. It
|
//! This crate is a high performance `git-config` file reader and writer. It
|
||||||
//! exposes a high level API to parse, read, and write [`git-config` files],
|
//! exposes a high level API to parse, read, and write [`git-config` files],
|
||||||
|
|
|
@ -18,8 +18,8 @@ use nom::error::{Error as NomError, ErrorKind};
|
||||||
use nom::multi::{many0, many1};
|
use nom::multi::{many0, many1};
|
||||||
use nom::sequence::delimited;
|
use nom::sequence::delimited;
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::iter::FusedIterator;
|
use std::iter::FusedIterator;
|
||||||
use std::{borrow::Cow, error::Error};
|
|
||||||
use std::{convert::TryFrom, fmt::Display};
|
use std::{convert::TryFrom, fmt::Display};
|
||||||
|
|
||||||
/// Syntactic events that occurs in the config. Despite all these variants
|
/// Syntactic events that occurs in the config. Despite all these variants
|
||||||
|
@ -74,23 +74,15 @@ impl Display for Event<'_> {
|
||||||
/// as read. Consider [`Event::as_bytes`] for one-to-one reading.
|
/// as read. Consider [`Event::as_bytes`] for one-to-one reading.
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
Self::Value(e) | Self::ValueNotDone(e) | Self::ValueDone(e) => {
|
||||||
|
match std::str::from_utf8(e) {
|
||||||
|
Ok(e) => e.fmt(f),
|
||||||
|
Err(_) => write!(f, "{:02x?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
Self::Comment(e) => e.fmt(f),
|
Self::Comment(e) => e.fmt(f),
|
||||||
Self::SectionHeader(e) => e.fmt(f),
|
Self::SectionHeader(e) => e.fmt(f),
|
||||||
Self::Key(e) => e.fmt(f),
|
Self::Key(e) | Self::Newline(e) | Self::Whitespace(e) => e.fmt(f),
|
||||||
Self::Value(e) => match std::str::from_utf8(e) {
|
|
||||||
Ok(e) => e.fmt(f),
|
|
||||||
Err(_) => write!(f, "{:02x?}", e),
|
|
||||||
},
|
|
||||||
Self::Newline(e) => e.fmt(f),
|
|
||||||
Self::ValueNotDone(e) => match std::str::from_utf8(e) {
|
|
||||||
Ok(e) => e.fmt(f),
|
|
||||||
Err(_) => write!(f, "{:02x?}", e),
|
|
||||||
},
|
|
||||||
Self::ValueDone(e) => match std::str::from_utf8(e) {
|
|
||||||
Ok(e) => e.fmt(f),
|
|
||||||
Err(_) => write!(f, "{:02x?}", e),
|
|
||||||
},
|
|
||||||
Self::Whitespace(e) => e.fmt(f),
|
|
||||||
Self::KeyValueSeparator => write!(f, "="),
|
Self::KeyValueSeparator => write!(f, "="),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,26 +178,26 @@ impl Display for ParsedComment<'_> {
|
||||||
/// occurred, as well as the last parser node and the remaining data to be
|
/// occurred, as well as the last parser node and the remaining data to be
|
||||||
/// parsed.
|
/// parsed.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
pub struct ParserError<'a> {
|
pub struct Error<'a> {
|
||||||
line_number: usize,
|
line_number: usize,
|
||||||
last_attempted_parser: ParserNode,
|
last_attempted_parser: ParserNode,
|
||||||
parsed_until: &'a [u8],
|
parsed_until: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParserError<'_> {
|
impl Error<'_> {
|
||||||
/// The one-indexed line number where the error occurred. This is determined
|
/// The one-indexed line number where the error occurred. This is determined
|
||||||
/// by the number of newlines that were successfully parsed.
|
/// by the number of newlines that were successfully parsed.
|
||||||
pub fn line_number(&self) -> usize {
|
pub const fn line_number(&self) -> usize {
|
||||||
self.line_number + 1
|
self.line_number + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The remaining data that was left unparsed.
|
/// The remaining data that was left unparsed.
|
||||||
pub fn remaining_data(&self) -> &[u8] {
|
pub const fn remaining_data(&self) -> &[u8] {
|
||||||
self.parsed_until
|
self.parsed_until
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ParserError<'_> {
|
impl Display for Error<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
let data_size = self.parsed_until.len();
|
let data_size = self.parsed_until.len();
|
||||||
let data = std::str::from_utf8(self.parsed_until);
|
let data = std::str::from_utf8(self.parsed_until);
|
||||||
|
@ -235,7 +227,7 @@ impl Display for ParserError<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ParserError<'_> {}
|
impl std::error::Error for Error<'_> {}
|
||||||
|
|
||||||
/// A list of parsers that parsing can fail on. This is used for pretty-printing
|
/// A list of parsers that parsing can fail on. This is used for pretty-printing
|
||||||
/// errors
|
/// errors
|
||||||
|
@ -510,24 +502,21 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Consumes the parser to produce an iterator of Events.
|
/// Consumes the parser to produce an iterator of Events.
|
||||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||||
|
#[allow(clippy::should_implement_trait)]
|
||||||
pub fn into_iter(self) -> impl Iterator<Item = Event<'a>> + FusedIterator {
|
pub fn into_iter(self) -> impl Iterator<Item = Event<'a>> + FusedIterator {
|
||||||
// Can't impl IntoIter without allocating.and using a generic associated type
|
// Can't impl IntoIter without allocating.and using a generic associated type
|
||||||
// TODO: try harder?
|
// TODO: try harder?
|
||||||
let section_iter = self
|
let section_iter = self.sections.into_iter().flat_map(|section| {
|
||||||
.sections
|
|
||||||
.into_iter()
|
|
||||||
.map(|section| {
|
|
||||||
vec![Event::SectionHeader(section.section_header)]
|
vec![Event::SectionHeader(section.section_header)]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(section.events)
|
.chain(section.events)
|
||||||
})
|
});
|
||||||
.flatten();
|
|
||||||
self.frontmatter.into_iter().chain(section_iter)
|
self.frontmatter.into_iter().chain(section_iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a str> for Parser<'a> {
|
impl<'a> TryFrom<&'a str> for Parser<'a> {
|
||||||
type Error = ParserError<'a>;
|
type Error = Error<'a>;
|
||||||
|
|
||||||
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
|
fn try_from(value: &'a str) -> Result<Self, Self::Error> {
|
||||||
parse_from_str(value)
|
parse_from_str(value)
|
||||||
|
@ -535,7 +524,7 @@ impl<'a> TryFrom<&'a str> for Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a [u8]> for Parser<'a> {
|
impl<'a> TryFrom<&'a [u8]> for Parser<'a> {
|
||||||
type Error = ParserError<'a>;
|
type Error = Error<'a>;
|
||||||
|
|
||||||
fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
|
fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
|
||||||
parse_from_bytes(value)
|
parse_from_bytes(value)
|
||||||
|
@ -552,7 +541,7 @@ impl<'a> TryFrom<&'a [u8]> for Parser<'a> {
|
||||||
/// Returns an error if the string provided is not a valid `git-config`.
|
/// Returns an error if the string provided is not a valid `git-config`.
|
||||||
/// This generally is due to either invalid names or if there's extraneous
|
/// This generally is due to either invalid names or if there's extraneous
|
||||||
/// data succeeding valid `git-config` data.
|
/// data succeeding valid `git-config` data.
|
||||||
pub fn parse_from_str(input: &str) -> Result<Parser<'_>, ParserError> {
|
pub fn parse_from_str(input: &str) -> Result<Parser<'_>, Error> {
|
||||||
parse_from_bytes(input.as_bytes())
|
parse_from_bytes(input.as_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +555,7 @@ pub fn parse_from_str(input: &str) -> Result<Parser<'_>, ParserError> {
|
||||||
/// Returns an error if the string provided is not a valid `git-config`.
|
/// Returns an error if the string provided is not a valid `git-config`.
|
||||||
/// This generally is due to either invalid names or if there's extraneous
|
/// This generally is due to either invalid names or if there's extraneous
|
||||||
/// data succeeding valid `git-config` data.
|
/// data succeeding valid `git-config` data.
|
||||||
pub fn parse_from_bytes(input: &[u8]) -> Result<Parser<'_>, ParserError> {
|
pub fn parse_from_bytes(input: &[u8]) -> Result<Parser<'_>, Error> {
|
||||||
let mut newlines = 0;
|
let mut newlines = 0;
|
||||||
let (i, frontmatter) = many0(alt((
|
let (i, frontmatter) = many0(alt((
|
||||||
map(comment, Event::Comment),
|
map(comment, Event::Comment),
|
||||||
|
@ -595,7 +584,7 @@ pub fn parse_from_bytes(input: &[u8]) -> Result<Parser<'_>, ParserError> {
|
||||||
let mut node = ParserNode::SectionHeader;
|
let mut node = ParserNode::SectionHeader;
|
||||||
|
|
||||||
let maybe_sections = many1(|i| section(i, &mut node))(i);
|
let maybe_sections = many1(|i| section(i, &mut node))(i);
|
||||||
let (i, sections) = maybe_sections.map_err(|_| ParserError {
|
let (i, sections) = maybe_sections.map_err(|_| Error {
|
||||||
line_number: newlines,
|
line_number: newlines,
|
||||||
last_attempted_parser: node,
|
last_attempted_parser: node,
|
||||||
parsed_until: i,
|
parsed_until: i,
|
||||||
|
@ -612,7 +601,7 @@ pub fn parse_from_bytes(input: &[u8]) -> Result<Parser<'_>, ParserError> {
|
||||||
// This needs to happen after we collect sections, otherwise the line number
|
// This needs to happen after we collect sections, otherwise the line number
|
||||||
// will be off.
|
// will be off.
|
||||||
if !i.is_empty() {
|
if !i.is_empty() {
|
||||||
return Err(ParserError {
|
return Err(Error {
|
||||||
line_number: newlines,
|
line_number: newlines,
|
||||||
last_attempted_parser: node,
|
last_attempted_parser: node,
|
||||||
parsed_until: i,
|
parsed_until: i,
|
||||||
|
@ -714,7 +703,7 @@ fn section_header(i: &[u8]) -> IResult<&[u8], ParsedSectionHeader> {
|
||||||
let header = match find_legacy_subsection_separator(name) {
|
let header = match find_legacy_subsection_separator(name) {
|
||||||
Some(index) => ParsedSectionHeader {
|
Some(index) => ParsedSectionHeader {
|
||||||
name: Cow::Borrowed(&name[..index]),
|
name: Cow::Borrowed(&name[..index]),
|
||||||
separator: name.get(index..index + 1).map(|slice| Cow::Borrowed(slice)),
|
separator: name.get(index..=index).map(|slice| Cow::Borrowed(slice)),
|
||||||
subsection_name: name.get(index + 1..).map(|slice| Cow::Borrowed(slice)),
|
subsection_name: name.get(index + 1..).map(|slice| Cow::Borrowed(slice)),
|
||||||
},
|
},
|
||||||
None => ParsedSectionHeader {
|
None => ParsedSectionHeader {
|
||||||
|
@ -859,7 +848,7 @@ fn value_impl<'a, 'b>(i: &'a [u8], events: &'b mut Vec<Event<'a>>) -> IResult<&'
|
||||||
partial_value_found = true;
|
partial_value_found = true;
|
||||||
events.push(Event::ValueNotDone(Cow::Borrowed(&i[offset..index - 1])));
|
events.push(Event::ValueNotDone(Cow::Borrowed(&i[offset..index - 1])));
|
||||||
events.push(Event::Newline(Cow::Borrowed(
|
events.push(Event::Newline(Cow::Borrowed(
|
||||||
std::str::from_utf8(&i[index..index + 1]).unwrap(),
|
std::str::from_utf8(&i[index..=index]).unwrap(),
|
||||||
)));
|
)));
|
||||||
offset = index + 1;
|
offset = index + 1;
|
||||||
parsed_index = 0;
|
parsed_index = 0;
|
||||||
|
|
|
@ -391,7 +391,7 @@ pub enum IntegerSuffix {
|
||||||
|
|
||||||
impl IntegerSuffix {
|
impl IntegerSuffix {
|
||||||
/// Returns the number of bits that the suffix shifts left by.
|
/// Returns the number of bits that the suffix shifts left by.
|
||||||
pub fn bitwise_offset(&self) -> usize {
|
pub const fn bitwise_offset(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
Self::Kibi => 10,
|
Self::Kibi => 10,
|
||||||
Self::Mebi => 20,
|
Self::Mebi => 20,
|
||||||
|
@ -461,12 +461,12 @@ pub struct Color {
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
/// Returns the foreground color, if any.
|
/// Returns the foreground color, if any.
|
||||||
pub fn foreground(&self) -> Option<ColorValue> {
|
pub const fn foreground(&self) -> Option<ColorValue> {
|
||||||
self.foreground
|
self.foreground
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the background color, if any.
|
/// Returns the background color, if any.
|
||||||
pub fn background(&self) -> Option<ColorValue> {
|
pub const fn background(&self) -> Option<ColorValue> {
|
||||||
self.background
|
self.background
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue