windows_registry/
value.rs1use super::*;
2
3#[derive(Clone, PartialEq, Eq, Debug)]
5pub struct Value {
6 pub(crate) data: Data,
7 pub(crate) ty: Type,
8}
9
10impl Value {
11 pub fn ty(&self) -> Type {
13 self.ty
14 }
15
16 pub fn set_ty(&mut self, ty: Type) {
18 self.ty = ty;
19 }
20
21 pub fn as_wide(&self) -> &[u16] {
23 self.data.as_wide()
24 }
25}
26
27impl core::ops::Deref for Value {
28 type Target = [u8];
29
30 fn deref(&self) -> &[u8] {
31 &self.data
32 }
33}
34
35impl AsRef<[u8]> for Value {
36 fn as_ref(&self) -> &[u8] {
37 &self.data
38 }
39}
40
41impl From<u32> for Value {
42 fn from(from: u32) -> Self {
43 Self {
44 data: from.to_le_bytes().into(),
45 ty: Type::U32,
46 }
47 }
48}
49
50impl TryFrom<Value> for u32 {
51 type Error = Error;
52 fn try_from(from: Value) -> Result<Self> {
53 Ok(from_le_bytes(from.ty, &from)?.try_into()?)
54 }
55}
56
57impl From<u64> for Value {
58 fn from(from: u64) -> Self {
59 Self {
60 data: from.to_le_bytes().into(),
61 ty: Type::U64,
62 }
63 }
64}
65
66impl TryFrom<Value> for u64 {
67 type Error = Error;
68 fn try_from(from: Value) -> Result<Self> {
69 from_le_bytes(from.ty, &from)
70 }
71}
72
73impl TryFrom<Value> for String {
74 type Error = Error;
75 fn try_from(from: Value) -> Result<Self> {
76 match from.ty {
77 Type::String | Type::ExpandString => Ok(Self::from_utf16(trim(from.data.as_wide()))?),
78 _ => Err(invalid_data()),
79 }
80 }
81}
82
83impl From<&str> for Value {
84 fn from(from: &str) -> Self {
85 Self {
86 data: Data::from_slice(pcwstr(from).as_bytes()),
87 ty: Type::String,
88 }
89 }
90}
91
92impl TryFrom<Value> for Vec<String> {
93 type Error = Error;
94 fn try_from(from: Value) -> Result<Self> {
95 match from.ty {
96 Type::MultiString => Ok(from
97 .data
98 .as_wide()
99 .split(|c| *c == 0)
100 .map(String::from_utf16_lossy)
101 .collect()),
102 _ => Ok(vec![String::try_from(from)?]),
103 }
104 }
105}
106
107impl TryFrom<Value> for HSTRING {
108 type Error = Error;
109 fn try_from(from: Value) -> Result<Self> {
110 match from.ty {
111 Type::String | Type::ExpandString => Ok(Self::from_wide(trim(from.data.as_wide()))),
112 _ => Err(invalid_data()),
113 }
114 }
115}
116
117impl From<&HSTRING> for Value {
118 fn from(from: &HSTRING) -> Self {
119 Self {
120 data: Data::from_slice(as_bytes(from)),
121 ty: Type::String,
122 }
123 }
124}
125
126impl From<&[u8]> for Value {
127 fn from(from: &[u8]) -> Self {
128 Self {
129 data: Data::from_slice(from),
130 ty: Type::Bytes,
131 }
132 }
133}
134
135impl<const N: usize> From<[u8; N]> for Value {
136 fn from(from: [u8; N]) -> Self {
137 Self {
138 data: Data::from_slice(&from),
139 ty: Type::Bytes,
140 }
141 }
142}
143
144fn trim(mut wide: &[u16]) -> &[u16] {
145 while wide.last() == Some(&0) {
146 wide = &wide[..wide.len() - 1];
147 }
148
149 wide
150}