Closed bluebear94 closed 1 month ago
This seems to overlap somewhat with the SlicePattern
API which should be considered, and perhaps this could just be included in that, since str::trim_*_matches
are similar to this API, and a method using SlicePattern with the proposed API could be analogous to that.
If this is not included in the SlicePattern API:
I think these should be implemented on [T]
directly, rather than on &(mut) [T]
. This would match existing APIs like slice::split
and str::trim_matches
. Also, the current signatures of trim_*_mut
are not implementable (or are unsound), since you cannot subslice a &'long mut U
from a &'short &'long mut U
.
I think the closure passed to trim_*_mut
should take &mut T
, so we don't have a repeat of Vec::retain
vs Vec::retain_mut
.
Concretely:
// `f` gives the predicate for elements to trim
impl<T> [T] {
pub fn trim<F>(&self, f: F) -> &[T]
where F: Fn(&T) -> bool;
pub fn trim_start<F>(&self, f: F) -> &[T]
where F: Fn(&T) -> bool;
pub fn trim_end<F>(&self, f: F) -> &[T]
where F: Fn(&T) -> bool;
pub fn trim_mut<F>(&mut self, f: F) -> &mut [T]
where F: Fn(&mut T) -> bool;
pub fn trim_start_mut<F>(&mut self, f: F) -> &mut [T]
where F: Fn(&mut T) -> bool;
pub fn trim_end_mut<F>(&mut self, f: F) -> &mut [T]
where F: Fn(&mut T) -> bool;
}
We discussed this in the libs-api meeting today. We are happy to accept this API with several changes.
These methods should follow the trim_matches
naming scheme like the methods on str
since they take an argument while the bare trim
methods on str
don't and will trim whitespace.
Additionally, these should use the SlicePattern
API, which will need to be extended to support using a Fn
as a slice pattern.
Proposal
Problem statement
In Typst, we need to inspect the part of a slice from the first “non-ignorant” element to the last (see typst/typst#4544).
Motivating examples or use cases
The most readable solution is
but this doesn’t optimize as well as the following:
Alternatively, we can loop with
split_first
orsplit_last
.Also see an idealized example on the playground for easy ASM viewing.
Trying to loop on slice matches gives a borrow checker error when the subslice needs to be mutable:
Solution sketch
Add
slice::{trim, trim_start, trim_end}
functions, as well as their mutable counterparts:Alternatives
We could omit
trim
andtrim_mut
, since these can be expressed as a sequence oftrim_start
andtrim_end
.We could add a trait for peekable iterators (#176), allowing this operation to be implemented using iterator-based methods.
We could omit the
_mut
methods, but this wouldn’t cover the case when you’d later need to mutate the subslice. Alternatively, we could add_mut
variants for thetrim_ascii
methods.We could bound
F
byFnMut(&T) -> bool
instead ofFn(&T) -> bool
, but that would make the order of element checking observable. This isn’t a problem fortrim_start
andtrim_end
, but it is fortrim
. Alternatively, we could do this for the methods other thantrim
andtrim_mut
.For the
_mut
methods, we could pass in amut
reference to the callback.Links and related work
Issue: typst/typst#4544
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution: