visit_bytes/
lib.rs

1#![cfg_attr(not(feature = "camino"), no_std)]
2#![forbid(unsafe_code)]
3
4/** `visit-bytes` applies a visitor pattern to byte sequences,
5  and is primarily used for (byte-)string rewriting in
6  diverse/heterogenous structures (e.g. in-memory directory trees)
7**/
8
9pub trait Element {
10    fn accept<V: Visitor>(&self, visitor: &mut V);
11    fn accept_mut<V: VisitorMut>(&mut self, visitor: &mut V);
12}
13
14pub trait Visitor {
15    fn visit_bytes(&mut self, bytes: &[u8]);
16}
17
18pub trait VisitorMut {
19    fn visit_bytes(&mut self, bytes: &mut [u8]);
20}
21
22impl Element for [u8] {
23    fn accept<V: Visitor>(&self, visitor: &mut V) {
24        visitor.visit_bytes(self);
25    }
26    fn accept_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
27        visitor.visit_bytes(self);
28    }
29}
30
31#[cfg(feature = "alloc")]
32extern crate alloc;
33
34#[cfg(feature = "alloc")]
35use alloc::string::String;
36
37#[cfg(feature = "alloc")]
38impl Element for String {
39    fn accept<V: Visitor>(&self, visitor: &mut V) {
40        visitor.visit_bytes(self.as_bytes());
41    }
42    fn accept_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
43        let mut bytes = self.as_bytes().to_vec();
44        visitor.visit_bytes(&mut bytes[..]);
45        *self = Self::from_utf8(bytes).expect("illegal hash characters used");
46    }
47}
48
49#[cfg(feature = "camino")]
50use camino_::Utf8PathBuf;
51
52#[cfg(feature = "camino")]
53impl Element for Utf8PathBuf {
54    fn accept<V: Visitor>(&self, visitor: &mut V) {
55        visitor.visit_bytes(self.as_str().as_bytes());
56    }
57    fn accept_mut<V: VisitorMut>(&mut self, visitor: &mut V) {
58        let mut s = String::from(core::mem::replace(self, Utf8PathBuf::from("")));
59        s.accept_mut(visitor);
60        *self = s.into();
61    }
62}