tonic_richer_error/std_messages/
help.rs1use prost::{DecodeError, Message};
2use prost_types::Any;
3
4use super::super::pb;
5use super::super::{FromAny, IntoAny};
6
7#[derive(Clone, Debug)]
9pub struct HelpLink {
10 pub description: String,
12
13 pub url: String,
15}
16
17impl HelpLink {
18 pub fn new(description: impl Into<String>, url: impl Into<String>) -> Self {
20 HelpLink {
21 description: description.into(),
22 url: url.into(),
23 }
24 }
25}
26
27#[derive(Clone, Debug)]
33pub struct Help {
34 pub links: Vec<HelpLink>,
36}
37
38impl Help {
39 pub const TYPE_URL: &'static str = "type.googleapis.com/google.rpc.Help";
41
42 pub fn new(links: Vec<HelpLink>) -> Self {
44 Help { links }
45 }
46
47 pub fn with_link(description: impl Into<String>, url: impl Into<String>) -> Self {
49 Help {
50 links: vec![HelpLink {
51 description: description.into(),
52 url: url.into(),
53 }],
54 }
55 }
56}
57
58impl Help {
59 pub fn add_link(
61 &mut self,
62 description: impl Into<String>,
63 url: impl Into<String>,
64 ) -> &mut Self {
65 self.links.append(&mut vec![HelpLink {
66 description: description.into(),
67 url: url.into(),
68 }]);
69 self
70 }
71
72 pub fn is_empty(&self) -> bool {
75 self.links.is_empty()
76 }
77}
78
79impl IntoAny for Help {
80 fn into_any(self) -> Any {
81 let detail_data = pb::Help {
82 links: self
83 .links
84 .into_iter()
85 .map(|v| pb::help::Link {
86 description: v.description,
87 url: v.url,
88 })
89 .collect(),
90 };
91
92 Any {
93 type_url: Help::TYPE_URL.to_string(),
94 value: detail_data.encode_to_vec(),
95 }
96 }
97}
98
99impl FromAny for Help {
100 fn from_any(any: Any) -> Result<Self, DecodeError> {
101 let buf: &[u8] = &any.value;
102 let help = pb::Help::decode(buf)?;
103
104 let quota_failure = Help {
105 links: help
106 .links
107 .into_iter()
108 .map(|v| HelpLink {
109 description: v.description,
110 url: v.url,
111 })
112 .collect(),
113 };
114
115 Ok(quota_failure)
116 }
117}
118
119#[cfg(test)]
120mod tests {
121
122 use super::super::super::{FromAny, IntoAny};
123 use super::Help;
124
125 #[test]
126 fn gen_quota_failure() {
127 let mut help = Help::new(Vec::new());
128 let formatted = format!("{:?}", help);
129
130 println!("empty Help -> {formatted}");
131
132 let expected = "Help { links: [] }";
133
134 assert!(
135 formatted.eq(expected),
136 "empty Help differs from expected result"
137 );
138
139 assert!(
140 help.is_empty(),
141 "empty Help returns 'false' from .is_empty()"
142 );
143
144 help.add_link("link to resource a", "resource-a.example.local")
145 .add_link("link to resource b", "resource-b.example.local");
146
147 let formatted = format!("{:?}", help);
148
149 println!("filled Help -> {formatted}");
150
151 let expected_filled = "Help { links: [HelpLink { description: \"link to resource a\", url: \"resource-a.example.local\" }, HelpLink { description: \"link to resource b\", url: \"resource-b.example.local\" }] }";
152
153 assert!(
154 formatted.eq(expected_filled),
155 "filled Help differs from expected result"
156 );
157
158 assert!(
159 help.is_empty() == false,
160 "filled Help returns 'true' from .is_empty()"
161 );
162
163 let gen_any = help.into_any();
164
165 let formatted = format!("{:?}", gen_any);
166
167 println!("Any generated from Help -> {formatted}");
168
169 let expected = "Any { type_url: \"type.googleapis.com/google.rpc.Help\", value: [10, 46, 10, 18, 108, 105, 110, 107, 32, 116, 111, 32, 114, 101, 115, 111, 117, 114, 99, 101, 32, 97, 18, 24, 114, 101, 115, 111, 117, 114, 99, 101, 45, 97, 46, 101, 120, 97, 109, 112, 108, 101, 46, 108, 111, 99, 97, 108, 10, 46, 10, 18, 108, 105, 110, 107, 32, 116, 111, 32, 114, 101, 115, 111, 117, 114, 99, 101, 32, 98, 18, 24, 114, 101, 115, 111, 117, 114, 99, 101, 45, 98, 46, 101, 120, 97, 109, 112, 108, 101, 46, 108, 111, 99, 97, 108] }";
170
171 assert!(
172 formatted.eq(expected),
173 "Any from filled Help differs from expected result"
174 );
175
176 let br_details = match Help::from_any(gen_any) {
177 Err(error) => panic!("Error generating Help from Any: {:?}", error),
178 Ok(from_any) => from_any,
179 };
180
181 let formatted = format!("{:?}", br_details);
182
183 println!("Help generated from Any -> {formatted}");
184
185 assert!(
186 formatted.eq(expected_filled),
187 "Help from Any differs from expected result"
188 );
189 }
190}