Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Changed

- Resolved all `clippy` (`clippy::all` + `clippy::pedantic`) and `rustc` lint
warnings across the full feature powerset — including newer-toolchain lints
(`mismatched_lifetime_syntaxes`) and feature-combination dead-code warnings.
Internal only; no public API changes.

## [0.8.0] 2026-07-26

### Added
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ In the case of [`PointerBuf::parse`], the [`ParseError`] is always wrapped in a
Licensed under either of

- Apache License, Version 2.0
([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license
([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)

at your convenience.

Expand Down
7 changes: 6 additions & 1 deletion src/assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ impl Diagnostic for Error {
}

fn labels(&self, origin: &Self::Subject) -> Option<Box<dyn Iterator<Item = Label>>> {
use alloc::format;
let position = self.position();
let token = origin.get(position)?;
let offset = if self.offset() + 1 < origin.as_str().len() {
Expand Down Expand Up @@ -264,6 +265,7 @@ mod json {
use serde_json::{map::Entry, Map, Value};

fn expand(mut remaining: &Pointer, mut value: Value) -> Value {
use alloc::vec;
while let Some((ptr, tok)) = remaining.split_back() {
remaining = ptr;
match tok.encoded() {
Expand Down Expand Up @@ -430,11 +432,12 @@ mod json {
mod toml {
use super::{Assign, Assigned, Error};
use crate::{Pointer, Token};
use alloc::{string::String, vec, vec::Vec};
use alloc::{string::String, vec::Vec};
use core::mem;
use toml::{map::Entry, map::Map, Value};

fn expand(mut remaining: &Pointer, mut value: Value) -> Value {
use alloc::vec;
while let Some((ptr, tok)) = remaining.split_back() {
remaining = ptr;
match tok.encoded() {
Expand Down Expand Up @@ -595,6 +598,8 @@ mod toml {
}
}

// `Assigned` is only referenced by the `json` and `toml` assignment impls.
#[cfg(any(feature = "json", feature = "toml"))]
enum Assigned<'v, V> {
Done(Option<V>),
Continue { next_dest: &'v mut V, same_value: V },
Expand Down
18 changes: 6 additions & 12 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ impl miette::SourceCode for StringOrToken {
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn miette::SpanContents<'a> + 'a>, miette::MietteError> {
let s: &str = &**self;
let s: &str = self;
s.read_span(span, context_lines_before, context_lines_after)
}
}
Expand Down Expand Up @@ -552,10 +552,7 @@ mod tests {

#[cfg(feature = "miette")]
{
let labels: Vec<_> = miette::Diagnostic::labels(&err)
.unwrap()
.into_iter()
.collect();
let labels: Vec<_> = miette::Diagnostic::labels(&err).unwrap().collect();
assert_eq!(
labels,
vec![miette::LabeledSpan::new(
Expand All @@ -567,7 +564,7 @@ mod tests {
}

let (src, sub) = err.decompose();
let labels: Vec<_> = src.labels(&sub).unwrap().into_iter().collect();
let labels: Vec<_> = src.labels(&sub).unwrap().collect();

assert_eq!(
labels,
Expand All @@ -582,25 +579,22 @@ mod tests {

#[cfg(feature = "miette")]
{
let labels: Vec<_> = miette::Diagnostic::labels(&err)
.unwrap()
.into_iter()
.collect();
let labels: Vec<_> = miette::Diagnostic::labels(&err).unwrap().collect();
assert_eq!(
labels,
vec![miette::LabeledSpan::new(Some("leading zeros".into()), 0, 5)]
);
}

let (src, sub) = err.decompose();
let labels: Vec<_> = src.labels(&sub).unwrap().into_iter().collect();
let labels: Vec<_> = src.labels(&sub).unwrap().collect();

assert_eq!(labels, vec![Label::new("leading zeros".into(), 0, 5)]);
}

#[test]
fn error_from_empty_string() {
let s = String::from("");
let s = String::new();
let err = Index::try_from(&s).diagnose(s).unwrap_err();

#[cfg(feature = "miette")]
Expand Down
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
clippy::similar_names
)]

#[cfg_attr(not(feature = "std"), macro_use)]
extern crate alloc;

#[cfg(feature = "assign")]
Expand Down
24 changes: 14 additions & 10 deletions src/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl Pointer {
}

/// Returns an iterator of `Token`s in the `Pointer`.
pub fn tokens(&self) -> Tokens {
pub fn tokens(&self) -> Tokens<'_> {
let mut s = self.0.split('/');
// skipping the first '/'
s.next();
Expand All @@ -141,7 +141,7 @@ impl Pointer {
}

/// Returns the last `Token` in the `Pointer`.
pub fn back(&self) -> Option<Token> {
pub fn back(&self) -> Option<Token<'_>> {
self.0
.rsplit_once('/')
// SAFETY: pointer is encoded
Expand All @@ -151,12 +151,12 @@ impl Pointer {
/// Returns the last token in the `Pointer`.
///
/// alias for `back`
pub fn last(&self) -> Option<Token> {
pub fn last(&self) -> Option<Token<'_>> {
self.back()
}

/// Returns the first `Token` in the `Pointer`.
pub fn front(&self) -> Option<Token> {
pub fn front(&self) -> Option<Token<'_>> {
if self.is_root() {
return None;
}
Expand All @@ -173,12 +173,12 @@ impl Pointer {
/// Returns the first `Token` in the `Pointer`.
///
/// alias for `front`
pub fn first(&self) -> Option<Token> {
pub fn first(&self) -> Option<Token<'_>> {
self.front()
}

/// Splits the `Pointer` into the first `Token` and a remainder `Pointer`.
pub fn split_front(&self) -> Option<(Token, &Self)> {
pub fn split_front(&self) -> Option<(Token<'_>, &Self)> {
if self.is_root() {
return None;
}
Expand Down Expand Up @@ -255,7 +255,7 @@ impl Pointer {
}

/// Splits the `Pointer` into the parent path and the last `Token`.
pub fn split_back(&self) -> Option<(&Self, Token)> {
pub fn split_back(&self) -> Option<(&Self, Token<'_>)> {
self.0.rsplit_once('/').map(|(front, back)| {
(
// SAFETY: we split at a token boundary, so front is a valid pointer
Expand Down Expand Up @@ -503,7 +503,7 @@ impl Pointer {
/// assert_eq!(components.next(), Some(Component::Token("b".into())));
/// assert_eq!(components.next(), None);
/// ```
pub fn components(&self) -> Components {
pub fn components(&self) -> Components<'_> {
self.into()
}

Expand Down Expand Up @@ -640,6 +640,7 @@ impl<'de: 'p, 'p> serde::Deserialize<'de> for &'p Pointer {
where
E: Error,
{
use alloc::format;
Pointer::parse(v).map_err(|err| {
Error::custom(format!("failed to parse json pointer\n\ncaused by:\n{err}"))
})
Expand Down Expand Up @@ -1022,7 +1023,7 @@ impl PointerBuf {
&mut self,
index: usize,
token: impl Into<Token<'t>>,
) -> Result<Option<Token>, ReplaceError> {
) -> Result<Option<Token<'_>>, ReplaceError> {
if self.is_root() {
return Err(ReplaceError {
count: self.count(),
Expand Down Expand Up @@ -2380,7 +2381,10 @@ mod tests {

#[test]
fn default_lifetime_is_correct() {
// if this compiles, we're good
// if this compiles, we're good: `unwrap_or_default` exercises
// `<&Pointer as Default>::default()` and must type-check with the
// borrowed lifetime (regression test for #111).
#[allow(clippy::unnecessary_literal_unwrap)]
fn or_default(ptr: &Pointer) -> &Pointer {
Some(ptr).unwrap_or_default()
}
Expand Down
7 changes: 6 additions & 1 deletion src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@
use crate::{
diagnostic::{diagnostic_url, Diagnostic, Label},
index::{OutOfBoundsError, ParseIndexError},
Pointer, PointerBuf, Token,
Pointer, PointerBuf,
};
// `Token` is only referenced by the `json`-gated `parse_index`.
#[cfg(feature = "json")]
use crate::Token;
use alloc::{boxed::Box, string::ToString};
use core::iter::once;

Expand Down Expand Up @@ -344,6 +347,8 @@ mod json {
}
}
}
// `parse_index` is only referenced by the `json` resolve impl.
#[cfg(feature = "json")]
fn parse_index(
token: Token,
array_len: usize,
Expand Down
21 changes: 6 additions & 15 deletions src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,15 +510,12 @@ mod tests {

let sub = String::from("a/b");
let err = Token::from_encoded(&sub).unwrap_err();
let labels: Vec<_> = err.labels(&sub).unwrap().into_iter().collect();
let labels: Vec<_> = err.labels(&sub).unwrap().collect();
assert_eq!(labels, vec![Label::new("invalid character".into(), 1, 1)]);
let err = err.into_report(sub);
#[cfg(feature = "miette")]
{
let labels: Vec<_> = miette::Diagnostic::labels(&err)
.unwrap()
.into_iter()
.collect();
let labels: Vec<_> = miette::Diagnostic::labels(&err).unwrap().collect();
assert_eq!(
labels,
vec![miette::LabeledSpan::new(
Expand All @@ -539,15 +536,12 @@ mod tests {

let sub = String::from("a~a");
let err = Token::from_encoded(&sub).unwrap_err();
let labels: Vec<_> = err.labels(&sub).unwrap().into_iter().collect();
let labels: Vec<_> = err.labels(&sub).unwrap().collect();
assert_eq!(labels, vec![Label::new("must be 0 or 1".into(), 2, 1)]);
let err = err.into_report(sub);
#[cfg(feature = "miette")]
{
let labels: Vec<_> = miette::Diagnostic::labels(&err)
.unwrap()
.into_iter()
.collect();
let labels: Vec<_> = miette::Diagnostic::labels(&err).unwrap().collect();
assert_eq!(
labels,
vec![miette::LabeledSpan::new(
Expand All @@ -567,18 +561,15 @@ mod tests {
);
let sub = String::from("a~");
let err = Token::from_encoded(&sub).unwrap_err();
let labels: Vec<_> = err.labels(&sub).unwrap().into_iter().collect();
let labels: Vec<_> = err.labels(&sub).unwrap().collect();
assert_eq!(
labels,
vec![Label::new("incomplete escape sequence".into(), 1, 1)]
);
let err = err.into_report(sub);
#[cfg(feature = "miette")]
{
let labels: Vec<_> = miette::Diagnostic::labels(&err)
.unwrap()
.into_iter()
.collect();
let labels: Vec<_> = miette::Diagnostic::labels(&err).unwrap().collect();
assert_eq!(
labels,
vec![miette::LabeledSpan::new(
Expand Down
Loading