1#![cfg_attr(not(feature = "camino"), no_std)]
2#![forbid(unsafe_code)]
3
4pub 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}