Skip to content

Commit 602da5c

Browse files
committed
Implement the Needle API for OsStr.
1 parent 18a59c0 commit 602da5c

File tree

5 files changed

+613
-5
lines changed

5 files changed

+613
-5
lines changed

src/libcore/slice/needles.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ where
401401
}
402402

403403
#[inline]
404-
pub fn next(&mut self, hay: &[T], range: Range<usize>) -> Option<Range<usize>> {
404+
pub(crate) fn next(&mut self, hay: &[T], range: Range<usize>) -> Option<Range<usize>> {
405405
if self.memory != usize::MAX {
406406
self.do_next::<ShortPeriod>(hay, range)
407407
} else {
@@ -469,7 +469,7 @@ where
469469
}
470470

471471
#[inline]
472-
pub fn next_back(&mut self, hay: &[T], range: Range<usize>) -> Option<Range<usize>> {
472+
pub(crate) fn next_back(&mut self, hay: &[T], range: Range<usize>) -> Option<Range<usize>> {
473473
if self.memory != usize::MAX {
474474
self.do_next_back::<ShortPeriod>(hay, range)
475475
} else {

src/libstd/ffi/os_str.rs

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ use crate::cmp;
55
use crate::hash::{Hash, Hasher};
66
use crate::rc::Rc;
77
use crate::sync::Arc;
8+
use crate::needle::{Hay, Haystack, Needle, Span, Searcher, ReverseSearcher, Consumer, ReverseConsumer};
89

9-
use crate::sys::os_str::{Buf, Slice};
10+
use crate::sys::os_str::{Buf, Slice, OsStrSearcher};
1011
use crate::sys_common::{AsInner, IntoInner, FromInner};
1112

13+
use core::slice::needles::{TwoWaySearcher, SliceSearcher, NaiveSearcher};
14+
1215
/// A type that can represent owned, mutable platform-native strings, but is
1316
/// cheaply inter-convertible with Rust strings.
1417
///
@@ -1246,3 +1249,166 @@ mod tests {
12461249
assert_eq!(OsString::from_wide(&[0xDF0D, 0xD83C]), &os_str[7..11]);
12471250
}
12481251
}
1252+
1253+
#[unstable(feature = "needle", issue = "56345")]
1254+
unsafe impl Hay for OsStr {
1255+
type Index = usize;
1256+
1257+
#[inline]
1258+
fn empty<'a>() -> &'a Self {
1259+
Self::new("")
1260+
}
1261+
1262+
#[inline]
1263+
fn start_index(&self) -> usize {
1264+
0
1265+
}
1266+
1267+
#[inline]
1268+
fn end_index(&self) -> usize {
1269+
self.len()
1270+
}
1271+
1272+
#[inline]
1273+
unsafe fn slice_unchecked(&self, range: ops::Range<usize>) -> &Self {
1274+
&self[range]
1275+
}
1276+
1277+
#[inline]
1278+
unsafe fn next_index(&self, index: usize) -> usize {
1279+
self.inner.next_index(index)
1280+
}
1281+
1282+
#[inline]
1283+
unsafe fn prev_index(&self, index: usize) -> usize {
1284+
self.inner.prev_index(index)
1285+
}
1286+
}
1287+
1288+
// use a macro here since the type of `hay.inner.inner` is platform dependent
1289+
// and we don't want to expose that type.
1290+
macro_rules! span_as_inner {
1291+
($span:expr) => {{
1292+
let (hay, range) = $span.into_parts();
1293+
unsafe { Span::from_parts(&hay.inner.inner, range) }
1294+
}}
1295+
}
1296+
1297+
fn span_as_inner_bytes(span: Span<&OsStr>) -> Span<&[u8]> {
1298+
let (hay, range) = span.into_parts();
1299+
unsafe { Span::from_parts(hay.inner.as_bytes_for_searcher(), range) }
1300+
}
1301+
1302+
#[unstable(feature = "needle", issue = "56345")]
1303+
unsafe impl<'p> Searcher<OsStr> for TwoWaySearcher<'p, u8> {
1304+
#[inline]
1305+
fn search(&mut self, span: Span<&OsStr>) -> Option<ops::Range<usize>> {
1306+
self.search(span_as_inner_bytes(span))
1307+
}
1308+
}
1309+
1310+
#[unstable(feature = "needle", issue = "56345")]
1311+
unsafe impl<'p> ReverseSearcher<OsStr> for TwoWaySearcher<'p, u8> {
1312+
#[inline]
1313+
fn rsearch(&mut self, span: Span<&OsStr>) -> Option<ops::Range<usize>> {
1314+
self.rsearch(span_as_inner_bytes(span))
1315+
}
1316+
}
1317+
1318+
#[unstable(feature = "needle", issue = "56345")]
1319+
unsafe impl<'p> Consumer<OsStr> for NaiveSearcher<'p, u8> {
1320+
#[inline]
1321+
fn consume(&mut self, span: Span<&OsStr>) -> Option<usize> {
1322+
self.consume(span_as_inner_bytes(span))
1323+
}
1324+
1325+
#[inline]
1326+
fn trim_start(&mut self, hay: &OsStr) -> usize {
1327+
self.trim_start(hay.inner.as_bytes_for_searcher())
1328+
}
1329+
}
1330+
1331+
#[unstable(feature = "needle", issue = "56345")]
1332+
unsafe impl<'p> ReverseConsumer<OsStr> for NaiveSearcher<'p, u8> {
1333+
#[inline]
1334+
fn rconsume(&mut self, span: Span<&OsStr>) -> Option<usize> {
1335+
self.rconsume(span_as_inner_bytes(span))
1336+
}
1337+
1338+
#[inline]
1339+
fn trim_end(&mut self, hay: &OsStr) -> usize {
1340+
self.trim_end(hay.inner.as_bytes_for_searcher())
1341+
}
1342+
}
1343+
1344+
#[unstable(feature = "needle", issue = "56345")]
1345+
unsafe impl<'p> Searcher<OsStr> for OsStrSearcher<SliceSearcher<'p, u8>> {
1346+
#[inline]
1347+
fn search(&mut self, span: Span<&OsStr>) -> Option<ops::Range<usize>> {
1348+
self.search(span_as_inner!(span))
1349+
}
1350+
}
1351+
1352+
#[unstable(feature = "needle", issue = "56345")]
1353+
unsafe impl<'p> ReverseSearcher<OsStr> for OsStrSearcher<SliceSearcher<'p, u8>> {
1354+
#[inline]
1355+
fn rsearch(&mut self, span: Span<&OsStr>) -> Option<ops::Range<usize>> {
1356+
self.rsearch(span_as_inner!(span))
1357+
}
1358+
}
1359+
1360+
#[unstable(feature = "needle", issue = "56345")]
1361+
unsafe impl<'p> Consumer<OsStr> for OsStrSearcher<NaiveSearcher<'p, u8>> {
1362+
#[inline]
1363+
fn consume(&mut self, span: Span<&OsStr>) -> Option<usize> {
1364+
self.consume(span_as_inner!(span))
1365+
}
1366+
1367+
#[inline]
1368+
fn trim_start(&mut self, hay: &OsStr) -> usize {
1369+
self.trim_start(&hay.inner.inner)
1370+
}
1371+
}
1372+
1373+
#[unstable(feature = "needle", issue = "56345")]
1374+
unsafe impl<'p> ReverseConsumer<OsStr> for OsStrSearcher<NaiveSearcher<'p, u8>> {
1375+
#[inline]
1376+
fn rconsume(&mut self, span: Span<&OsStr>) -> Option<usize> {
1377+
self.rconsume(span_as_inner!(span))
1378+
}
1379+
1380+
#[inline]
1381+
fn trim_end(&mut self, hay: &OsStr) -> usize {
1382+
self.trim_end(&hay.inner.inner)
1383+
}
1384+
}
1385+
1386+
#[unstable(feature = "needle", issue = "56345")]
1387+
impl<'p, H: Haystack<Target = OsStr>> Needle<H> for &'p OsStr {
1388+
type Searcher = OsStrSearcher<SliceSearcher<'p, u8>>;
1389+
type Consumer = OsStrSearcher<NaiveSearcher<'p, u8>>;
1390+
1391+
fn into_searcher(self) -> Self::Searcher {
1392+
self.inner.into_searcher()
1393+
}
1394+
1395+
fn into_consumer(self) -> Self::Consumer {
1396+
self.inner.into_consumer()
1397+
}
1398+
}
1399+
1400+
// FIXME cannot impl `Needle<(_: Haystack<Target = OsStr>)>` due to RFC 1672 being postponed.
1401+
// (need to wait for chalk)
1402+
#[unstable(feature = "needle", issue = "56345")]
1403+
impl<'h, 'p> Needle<&'h OsStr> for &'p str {
1404+
type Searcher = SliceSearcher<'p, u8>;
1405+
type Consumer = NaiveSearcher<'p, u8>;
1406+
1407+
fn into_searcher(self) -> Self::Searcher {
1408+
SliceSearcher::new(self.as_bytes())
1409+
}
1410+
1411+
fn into_consumer(self) -> Self::Consumer {
1412+
NaiveSearcher::new(self.as_bytes())
1413+
}
1414+
}

src/libstd/sys/windows/os_str.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
44
use crate::borrow::Cow;
55
use crate::fmt;
6-
use crate::sys_common::wtf8::{Wtf8, Wtf8Buf};
6+
use crate::sys_common::wtf8::{self, Wtf8, Wtf8Buf};
77
use crate::mem;
88
use crate::rc::Rc;
99
use crate::sync::Arc;
1010
use crate::ops::{Index, Range, RangeFrom, RangeTo};
1111
use crate::sys_common::{AsInner, IntoInner, FromInner};
12+
use core::slice::needles::{SliceSearcher, NaiveSearcher};
13+
use crate::needle::Hay;
1214

1315
#[derive(Clone, Hash)]
1416
pub struct Buf {
@@ -195,4 +197,26 @@ impl Slice {
195197
let rc = self.inner.into_rc();
196198
unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
197199
}
200+
201+
pub unsafe fn next_index(&self, index: usize) -> usize {
202+
self.inner.next_index(index)
203+
}
204+
205+
pub unsafe fn prev_index(&self, index: usize) -> usize {
206+
self.inner.prev_index(index)
207+
}
208+
209+
pub fn into_searcher(&self) -> OsStrSearcher<SliceSearcher<'_, u8>> {
210+
wtf8::new_wtf8_searcher(&self.inner)
211+
}
212+
213+
pub fn into_consumer(&self) -> OsStrSearcher<NaiveSearcher<'_, u8>> {
214+
wtf8::new_wtf8_consumer(&self.inner)
215+
}
216+
217+
pub fn as_bytes_for_searcher(&self) -> &[u8] {
218+
self.inner.as_inner()
219+
}
198220
}
221+
222+
pub use sys_common::wtf8::Wtf8Searcher as OsStrSearcher;

src/libstd/sys_common/os_str_bytes.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use crate::sync::Arc;
1212
use crate::sys_common::{FromInner, IntoInner, AsInner};
1313
use crate::sys_common::bytestring::debug_fmt_bytestring;
1414
use core::str::lossy::Utf8Lossy;
15+
use core::slice::needles::{SliceSearcher, NaiveSearcher};
16+
use needle::{Hay, Span, Searcher, ReverseSearcher, Consumer, ReverseConsumer};
1517

1618
#[derive(Clone, Hash)]
1719
pub(crate) struct Buf {
@@ -203,6 +205,71 @@ impl Slice {
203205
let rc: Rc<[u8]> = Rc::from(&self.inner);
204206
unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
205207
}
208+
209+
pub unsafe fn next_index(&self, index: usize) -> usize {
210+
self.inner.next_index(index)
211+
}
212+
213+
pub unsafe fn prev_index(&self, index: usize) -> usize {
214+
self.inner.prev_index(index)
215+
}
216+
217+
pub fn into_searcher(&self) -> OsStrSearcher<SliceSearcher<'_, u8>> {
218+
OsStrSearcher(SliceSearcher::new(&self.inner))
219+
}
220+
221+
pub fn into_consumer(&self) -> OsStrSearcher<NaiveSearcher<'_, u8>> {
222+
OsStrSearcher(NaiveSearcher::new(&self.inner))
223+
}
224+
225+
pub fn as_bytes_for_searcher(&self) -> &[u8] {
226+
&self.inner
227+
}
228+
}
229+
230+
#[unstable(feature = "needle", issue = "56345")]
231+
pub struct OsStrSearcher<S>(S);
232+
233+
#[unstable(feature = "needle", issue = "56345")]
234+
unsafe impl<'p> Searcher<[u8]> for OsStrSearcher<SliceSearcher<'p, u8>> {
235+
#[inline]
236+
fn search(&mut self, span: Span<&[u8]>) -> Option<Range<usize>> {
237+
self.0.search(span)
238+
}
239+
}
240+
241+
#[unstable(feature = "needle", issue = "56345")]
242+
unsafe impl<'p> Consumer<[u8]> for OsStrSearcher<NaiveSearcher<'p, u8>> {
243+
#[inline]
244+
fn consume(&mut self, span: Span<&[u8]>) -> Option<usize> {
245+
self.0.consume(span)
246+
}
247+
248+
#[inline]
249+
fn trim_start(&mut self, hay: &[u8]) -> usize {
250+
self.0.trim_start(hay)
251+
}
252+
}
253+
254+
#[unstable(feature = "needle", issue = "56345")]
255+
unsafe impl<'p> ReverseSearcher<[u8]> for OsStrSearcher<SliceSearcher<'p, u8>> {
256+
#[inline]
257+
fn rsearch(&mut self, span: Span<&[u8]>) -> Option<Range<usize>> {
258+
self.0.rsearch(span)
259+
}
260+
}
261+
262+
#[unstable(feature = "needle", issue = "56345")]
263+
unsafe impl<'p> ReverseConsumer<[u8]> for OsStrSearcher<NaiveSearcher<'p, u8>> {
264+
#[inline]
265+
fn rconsume(&mut self, span: Span<&[u8]>) -> Option<usize> {
266+
self.0.rconsume(span)
267+
}
268+
269+
#[inline]
270+
fn trim_end(&mut self, hay: &[u8]) -> usize {
271+
self.0.trim_end(hay)
272+
}
206273
}
207274

208275
/// Platform-specific extensions to [`OsString`].

0 commit comments

Comments
 (0)