vue_sfc/ast/block/attribute/
value.rs1use std::{
2 borrow::{Borrow, Cow},
3 fmt::Display,
4 ops::Deref,
5};
6
7pub use self::error::InvalidAttributeValue;
8
9mod error {
10 use std::error::Error;
11 use std::fmt::Display;
12
13 #[derive(Debug)]
16 pub struct InvalidAttributeValue(pub(super) char);
17
18 impl Display for InvalidAttributeValue {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 write!(f, "illegal char: `{}`", self.0)
21 }
22 }
23
24 impl Error for InvalidAttributeValue {}
25}
26
27#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
29#[must_use]
30pub struct AttributeValue<'a>(Cow<'a, str>);
31
32impl<'a> AttributeValue<'a> {
33 pub fn from_cow(src: Cow<'a, str>) -> Result<Self, InvalidAttributeValue> {
44 if src.contains('\u{0022}') && src.contains('\u{0027}') {
45 if let Some(ch) = src.chars().find(|ch| {
46 matches!(
47 ch,
48 '\u{0009}' | '\u{000A}' | '\u{000C}' | '\u{0020}' | '\u{003E}'
49 )
50 }) {
51 return Err(InvalidAttributeValue(ch));
52 }
53 }
54
55 Ok(Self(src))
56 }
57
58 pub unsafe fn from_cow_unchecked(src: Cow<'a, str>) -> Self {
67 if cfg!(debug_assertions) {
68 match Self::from_cow(src) {
69 Ok(val) => val,
70 Err(err) => {
71 panic!("AttributeValue::from_cow_unchecked(): {err}")
72 }
73 }
74 } else {
75 Self(src)
76 }
77 }
78
79 #[must_use]
80 pub fn as_str(&self) -> &str {
81 &self.0
82 }
83}
84
85impl Deref for AttributeValue<'_> {
86 type Target = str;
87
88 fn deref(&self) -> &Self::Target {
89 self.as_str()
90 }
91}
92
93impl Borrow<str> for AttributeValue<'_> {
94 fn borrow(&self) -> &str {
95 self.as_str()
96 }
97}
98
99impl Display for AttributeValue<'_> {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 self.as_str().fmt(f)
102 }
103}
104
105impl<'a> TryFrom<Cow<'a, str>> for AttributeValue<'a> {
106 type Error = InvalidAttributeValue;
107 fn try_from(value: Cow<'a, str>) -> Result<Self, Self::Error> {
108 Self::from_cow(value)
109 }
110}
111
112impl<'a> TryFrom<&'a str> for AttributeValue<'a> {
113 type Error = InvalidAttributeValue;
114 fn try_from(value: &'a str) -> Result<Self, Self::Error> {
115 Self::from_cow(Cow::Borrowed(value))
116 }
117}
118
119impl<'a> TryFrom<String> for AttributeValue<'a> {
120 type Error = InvalidAttributeValue;
121 fn try_from(value: String) -> Result<Self, Self::Error> {
122 Self::from_cow(Cow::Owned(value))
123 }
124}