Created
February 20, 2023 01:56
-
-
Save lffg/77d21c45026bd482f083f99699c7c466 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{ | |
io::{Cursor, Seek, SeekFrom}, | |
ops::RangeBounds, | |
}; | |
/// Tries to get a UTF-8 string from the given buffer at the provided range. | |
fn str_from_utf8_range(buf: &[u8], range: impl RangeBounds<usize>) -> Option<&str> { | |
buf.get((range.start_bound().cloned(), range.end_bound().cloned())) | |
.map(|slice| std::str::from_utf8(slice).expect("valid utf8")) | |
} | |
/// Returns the remaining slice as a string slice. Panics if encounters invalid | |
/// UTF-8 bytes. | |
fn rem_str<T: AsRef<[u8]>>(cur: &mut Cursor<T>) -> Option<&str> { | |
str_from_utf8_range(cur.get_ref().as_ref(), (cur.position() as usize)..) | |
} | |
/// Gets `n` bytes from the cursor and advances `n`. Panics if the underlying | |
/// value doesn't have enough capacity for a +n seek. | |
fn get_str<T: AsRef<[u8]>>(cur: &mut Cursor<T>, n: usize) -> String { | |
let buf = cur.get_ref().as_ref(); | |
let hi = cur.position() as usize + n; | |
assert!(hi <= buf.len()); // high bound must be within buf's bounds | |
let eaten = str_from_utf8_range(buf, (cur.position() as usize)..hi) | |
// SAFETY: The assertion above ensures one is always within bounds. | |
.unwrap() | |
.to_owned(); | |
// SAFETY: No I/O is involved. | |
cur.seek(SeekFrom::Current(n as i64)).unwrap(); | |
eaten | |
} | |
fn main() { | |
let buf = b"hello world"; | |
let mut cur = Cursor::new(buf); | |
println!("remaining is [{:?}]", rem_str(&mut cur)); | |
println!( | |
"got [{}], remaining is [{:?}]", | |
get_str(&mut cur, 5), | |
rem_str(&mut cur) | |
); | |
println!( | |
"got [{}], remaining is [{:?}]", | |
get_str(&mut cur, 1), | |
rem_str(&mut cur) | |
); | |
println!( | |
"got [{}], remaining is [{:?}]", | |
get_str(&mut cur, 5), | |
rem_str(&mut cur) | |
); | |
println!( | |
"got [{}], remaining is [{:?}]", | |
get_str(&mut cur, 0), | |
rem_str(&mut cur) | |
); | |
// Assuming one never seeks past the end of the buffer, `rem_str` will | |
// always return `Some("")`. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment