1use crate::serde::{SerdeError, SerializableStruct, ShapeDeserializer, ShapeSerializer};
9use crate::Schema;
10use aws_smithy_types::{BigDecimal, BigInteger, Blob, DateTime, Document};
11
12pub struct HttpStringSerializer {
14 output: String,
15}
16
17impl HttpStringSerializer {
18 pub fn new() -> Self {
20 Self {
21 output: String::new(),
22 }
23 }
24
25 pub fn finish(self) -> String {
27 self.output
28 }
29}
30
31impl super::FinishSerializer for HttpStringSerializer {
32 fn finish(self) -> Vec<u8> {
33 self.output.into_bytes()
34 }
35}
36
37impl Default for HttpStringSerializer {
38 fn default() -> Self {
39 Self::new()
40 }
41}
42
43impl ShapeSerializer for HttpStringSerializer {
44 fn write_struct(
45 &mut self,
46 _schema: &Schema,
47 _value: &dyn SerializableStruct,
48 ) -> Result<(), SerdeError> {
49 Err(SerdeError::UnsupportedOperation {
50 message: "structures cannot be serialized to strings".into(),
51 })
52 }
53
54 fn write_list(
55 &mut self,
56 _schema: &Schema,
57 write_elements: &dyn Fn(&mut dyn ShapeSerializer) -> Result<(), SerdeError>,
58 ) -> Result<(), SerdeError> {
59 write_elements(self)
61 }
62
63 fn write_map(
64 &mut self,
65 _schema: &Schema,
66 _write_entries: &dyn Fn(&mut dyn ShapeSerializer) -> Result<(), SerdeError>,
67 ) -> Result<(), SerdeError> {
68 Err(SerdeError::UnsupportedOperation {
69 message: "maps cannot be serialized to strings".into(),
70 })
71 }
72
73 fn write_boolean(&mut self, _schema: &Schema, value: bool) -> Result<(), SerdeError> {
74 if !self.output.is_empty() {
75 self.output.push(',');
76 }
77 self.output.push_str(if value { "true" } else { "false" });
78 Ok(())
79 }
80
81 fn write_byte(&mut self, _schema: &Schema, value: i8) -> Result<(), SerdeError> {
82 if !self.output.is_empty() {
83 self.output.push(',');
84 }
85 self.output.push_str(&value.to_string());
86 Ok(())
87 }
88
89 fn write_short(&mut self, _schema: &Schema, value: i16) -> Result<(), SerdeError> {
90 if !self.output.is_empty() {
91 self.output.push(',');
92 }
93 self.output.push_str(&value.to_string());
94 Ok(())
95 }
96
97 fn write_integer(&mut self, _schema: &Schema, value: i32) -> Result<(), SerdeError> {
98 if !self.output.is_empty() {
99 self.output.push(',');
100 }
101 self.output.push_str(&value.to_string());
102 Ok(())
103 }
104
105 fn write_long(&mut self, _schema: &Schema, value: i64) -> Result<(), SerdeError> {
106 if !self.output.is_empty() {
107 self.output.push(',');
108 }
109 self.output.push_str(&value.to_string());
110 Ok(())
111 }
112
113 fn write_float(&mut self, _schema: &Schema, value: f32) -> Result<(), SerdeError> {
114 if !self.output.is_empty() {
115 self.output.push(',');
116 }
117 if value.is_nan() {
118 self.output.push_str("NaN");
119 } else if value.is_infinite() {
120 self.output.push_str(if value.is_sign_positive() {
121 "Infinity"
122 } else {
123 "-Infinity"
124 });
125 } else {
126 self.output.push_str(&value.to_string());
127 }
128 Ok(())
129 }
130
131 fn write_double(&mut self, _schema: &Schema, value: f64) -> Result<(), SerdeError> {
132 if !self.output.is_empty() {
133 self.output.push(',');
134 }
135 if value.is_nan() {
136 self.output.push_str("NaN");
137 } else if value.is_infinite() {
138 self.output.push_str(if value.is_sign_positive() {
139 "Infinity"
140 } else {
141 "-Infinity"
142 });
143 } else {
144 self.output.push_str(&value.to_string());
145 }
146 Ok(())
147 }
148
149 fn write_big_integer(
150 &mut self,
151 _schema: &Schema,
152 value: &BigInteger,
153 ) -> Result<(), SerdeError> {
154 if !self.output.is_empty() {
155 self.output.push(',');
156 }
157 self.output.push_str(value.as_ref());
158 Ok(())
159 }
160
161 fn write_big_decimal(
162 &mut self,
163 _schema: &Schema,
164 value: &BigDecimal,
165 ) -> Result<(), SerdeError> {
166 if !self.output.is_empty() {
167 self.output.push(',');
168 }
169 self.output.push_str(value.as_ref());
170 Ok(())
171 }
172
173 fn write_string(&mut self, _schema: &Schema, value: &str) -> Result<(), SerdeError> {
174 if !self.output.is_empty() {
175 self.output.push(',');
176 }
177 self.output.push_str(value);
178 Ok(())
179 }
180
181 fn write_blob(&mut self, _schema: &Schema, value: &Blob) -> Result<(), SerdeError> {
182 if !self.output.is_empty() {
183 self.output.push(',');
184 }
185 self.output
187 .push_str(&aws_smithy_types::base64::encode(value.as_ref()));
188 Ok(())
189 }
190
191 fn write_timestamp(&mut self, _schema: &Schema, value: &DateTime) -> Result<(), SerdeError> {
192 if !self.output.is_empty() {
193 self.output.push(',');
194 }
195 let formatted = value
198 .fmt(aws_smithy_types::date_time::Format::HttpDate)
199 .map_err(|e| SerdeError::WriteFailed {
200 message: format!("failed to format timestamp: {e}"),
201 })?;
202 self.output.push_str(&formatted);
203 Ok(())
204 }
205
206 fn write_document(&mut self, _schema: &Schema, _value: &Document) -> Result<(), SerdeError> {
207 Err(SerdeError::UnsupportedOperation {
208 message: "documents cannot be serialized to strings".into(),
209 })
210 }
211
212 fn write_null(&mut self, _schema: &Schema) -> Result<(), SerdeError> {
213 Err(SerdeError::UnsupportedOperation {
214 message: "null cannot be serialized to strings".into(),
215 })
216 }
217}
218
219pub struct HttpStringDeserializer<'a> {
221 input: std::borrow::Cow<'a, str>,
222 position: usize,
223}
224
225impl<'a> HttpStringDeserializer<'a> {
226 pub fn new(input: &'a str) -> Self {
228 Self {
229 input: std::borrow::Cow::Borrowed(input),
230 position: 0,
231 }
232 }
233
234 fn next_value(&mut self) -> Option<&str> {
235 if self.position >= self.input.len() {
236 return None;
237 }
238
239 let start = self.position;
240 if let Some(comma_pos) = self.input[start..].find(',') {
241 let end = start + comma_pos;
242 self.position = end + 1;
243 Some(&self.input[start..end])
244 } else {
245 self.position = self.input.len();
246 Some(&self.input[start..])
247 }
248 }
249
250 fn current_value(&self) -> &str {
251 &self.input[self.position..]
252 }
253}
254
255impl<'a> ShapeDeserializer for HttpStringDeserializer<'a> {
256 fn read_struct(
257 &mut self,
258 _schema: &Schema,
259 _consumer: &mut dyn FnMut(&Schema, &mut dyn ShapeDeserializer) -> Result<(), SerdeError>,
260 ) -> Result<(), SerdeError> {
261 Err(SerdeError::UnsupportedOperation {
262 message: "structures cannot be deserialized from strings".into(),
263 })
264 }
265
266 fn read_list(
267 &mut self,
268 _schema: &Schema,
269 _consumer: &mut dyn FnMut(&mut dyn ShapeDeserializer) -> Result<(), SerdeError>,
270 ) -> Result<(), SerdeError> {
271 Ok(())
274 }
275
276 fn read_map(
277 &mut self,
278 _schema: &Schema,
279 _consumer: &mut dyn FnMut(String, &mut dyn ShapeDeserializer) -> Result<(), SerdeError>,
280 ) -> Result<(), SerdeError> {
281 Err(SerdeError::UnsupportedOperation {
282 message: "maps cannot be deserialized from strings".into(),
283 })
284 }
285
286 fn read_boolean(&mut self, _schema: &Schema) -> Result<bool, SerdeError> {
287 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
288 message: "expected boolean value".into(),
289 })?;
290 value.parse().map_err(|_| SerdeError::InvalidInput {
291 message: format!("invalid boolean: {value}"),
292 })
293 }
294
295 fn read_byte(&mut self, _schema: &Schema) -> Result<i8, SerdeError> {
296 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
297 message: "expected byte value".into(),
298 })?;
299 value.parse().map_err(|_| SerdeError::InvalidInput {
300 message: format!("invalid byte: {value}"),
301 })
302 }
303
304 fn read_short(&mut self, _schema: &Schema) -> Result<i16, SerdeError> {
305 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
306 message: "expected short value".into(),
307 })?;
308 value.parse().map_err(|_| SerdeError::InvalidInput {
309 message: format!("invalid short: {value}"),
310 })
311 }
312
313 fn read_integer(&mut self, _schema: &Schema) -> Result<i32, SerdeError> {
314 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
315 message: "expected integer value".into(),
316 })?;
317 value.parse().map_err(|_| SerdeError::InvalidInput {
318 message: format!("invalid integer: {value}"),
319 })
320 }
321
322 fn read_long(&mut self, _schema: &Schema) -> Result<i64, SerdeError> {
323 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
324 message: "expected long value".into(),
325 })?;
326 value.parse().map_err(|_| SerdeError::InvalidInput {
327 message: format!("invalid long: {value}"),
328 })
329 }
330
331 fn read_float(&mut self, _schema: &Schema) -> Result<f32, SerdeError> {
332 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
333 message: "expected float value".into(),
334 })?;
335 match value {
336 "NaN" => Ok(f32::NAN),
337 "Infinity" => Ok(f32::INFINITY),
338 "-Infinity" => Ok(f32::NEG_INFINITY),
339 _ => value.parse().map_err(|_| SerdeError::InvalidInput {
340 message: format!("invalid float: {value}"),
341 }),
342 }
343 }
344
345 fn read_double(&mut self, _schema: &Schema) -> Result<f64, SerdeError> {
346 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
347 message: "expected double value".into(),
348 })?;
349 match value {
350 "NaN" => Ok(f64::NAN),
351 "Infinity" => Ok(f64::INFINITY),
352 "-Infinity" => Ok(f64::NEG_INFINITY),
353 _ => value.parse().map_err(|_| SerdeError::InvalidInput {
354 message: format!("invalid double: {value}"),
355 }),
356 }
357 }
358
359 fn read_big_integer(&mut self, _schema: &Schema) -> Result<BigInteger, SerdeError> {
360 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
361 message: "expected big integer value".into(),
362 })?;
363 use std::str::FromStr;
364 BigInteger::from_str(value).map_err(|_| SerdeError::InvalidInput {
365 message: format!("invalid big integer: {value}"),
366 })
367 }
368
369 fn read_big_decimal(&mut self, _schema: &Schema) -> Result<BigDecimal, SerdeError> {
370 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
371 message: "expected big decimal value".into(),
372 })?;
373 use std::str::FromStr;
374 BigDecimal::from_str(value).map_err(|_| SerdeError::InvalidInput {
375 message: format!("invalid big decimal: {value}"),
376 })
377 }
378
379 fn read_string(&mut self, _schema: &Schema) -> Result<String, SerdeError> {
380 self.next_value()
381 .ok_or_else(|| SerdeError::InvalidInput {
382 message: "expected string value".into(),
383 })
384 .map(|s| s.to_string())
385 }
386
387 fn read_blob(&mut self, _schema: &Schema) -> Result<Blob, SerdeError> {
388 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
389 message: "expected blob value".into(),
390 })?;
391 let decoded =
392 aws_smithy_types::base64::decode(value).map_err(|e| SerdeError::InvalidInput {
393 message: format!("invalid base64: {e}"),
394 })?;
395 Ok(Blob::new(decoded))
396 }
397
398 fn read_timestamp(&mut self, _schema: &Schema) -> Result<DateTime, SerdeError> {
399 let value = self.next_value().ok_or_else(|| SerdeError::InvalidInput {
400 message: "expected timestamp value".into(),
401 })?;
402 DateTime::from_str(value, aws_smithy_types::date_time::Format::HttpDate)
405 .or_else(|_| DateTime::from_str(value, aws_smithy_types::date_time::Format::DateTime))
406 .map_err(|e| SerdeError::InvalidInput {
407 message: format!("invalid timestamp: {e}"),
408 })
409 }
410
411 fn read_document(&mut self, _schema: &Schema) -> Result<Document, SerdeError> {
412 Err(SerdeError::UnsupportedOperation {
413 message: "documents cannot be deserialized from strings".into(),
414 })
415 }
416
417 fn is_null(&self) -> bool {
418 self.current_value().is_empty()
419 }
420
421 fn container_size(&self) -> Option<usize> {
422 Some(self.input.matches(',').count() + 1)
424 }
425}
426
427pub struct HttpStringCodec;
429
430impl crate::codec::Codec for HttpStringCodec {
431 type Serializer = HttpStringSerializer;
432 type Deserializer<'a> = HttpStringDeserializer<'a>;
433
434 fn create_serializer(&self) -> Self::Serializer {
435 HttpStringSerializer::new()
436 }
437
438 fn create_deserializer<'a>(&self, input: &'a [u8]) -> Self::Deserializer<'a> {
439 let input_str = std::str::from_utf8(input).unwrap_or("");
440 HttpStringDeserializer::new(input_str)
441 }
442}
443
444#[cfg(test)]
445mod tests {
446 use super::*;
447 use crate::prelude::*;
448
449 #[test]
450 fn test_serialize_boolean() {
451 let mut ser = HttpStringSerializer::new();
452 ser.write_boolean(&BOOLEAN, true).unwrap();
453 assert_eq!(ser.finish(), "true");
454
455 let mut ser = HttpStringSerializer::new();
456 ser.write_boolean(&BOOLEAN, false).unwrap();
457 assert_eq!(ser.finish(), "false");
458 }
459
460 #[test]
461 fn test_serialize_integers() {
462 let mut ser = HttpStringSerializer::new();
463 ser.write_byte(&BYTE, 42).unwrap();
464 assert_eq!(ser.finish(), "42");
465
466 let mut ser = HttpStringSerializer::new();
467 ser.write_integer(&INTEGER, -123).unwrap();
468 assert_eq!(ser.finish(), "-123");
469
470 let mut ser = HttpStringSerializer::new();
471 ser.write_long(&LONG, 9876543210).unwrap();
472 assert_eq!(ser.finish(), "9876543210");
473 }
474
475 #[test]
476 fn test_serialize_floats() {
477 let mut ser = HttpStringSerializer::new();
478 ser.write_float(&FLOAT, 3.15).unwrap();
479 assert_eq!(ser.finish(), "3.15");
480
481 let mut ser = HttpStringSerializer::new();
482 ser.write_float(&FLOAT, f32::NAN).unwrap();
483 assert_eq!(ser.finish(), "NaN");
484
485 let mut ser = HttpStringSerializer::new();
486 ser.write_float(&FLOAT, f32::INFINITY).unwrap();
487 assert_eq!(ser.finish(), "Infinity");
488 }
489
490 #[test]
491 fn test_serialize_string() {
492 let mut ser = HttpStringSerializer::new();
493 ser.write_string(&STRING, "hello world").unwrap();
494 assert_eq!(ser.finish(), "hello world");
495 }
496
497 #[test]
498 fn test_serialize_list() {
499 let mut ser = HttpStringSerializer::new();
500 ser.write_list(&STRING, &|s: &mut dyn ShapeSerializer| {
501 s.write_string(&STRING, "a")?;
502 s.write_string(&STRING, "b")?;
503 s.write_string(&STRING, "c")?;
504 Ok(())
505 })
506 .unwrap();
507 assert_eq!(ser.finish(), "a,b,c");
508 }
509
510 #[test]
511 fn test_serialize_blob() {
512 let mut ser = HttpStringSerializer::new();
513 let blob = Blob::new(vec![1, 2, 3, 4]);
514 ser.write_blob(&BLOB, &blob).unwrap();
515 assert_eq!(ser.finish(), "AQIDBA==");
517 }
518
519 #[test]
520 fn test_deserialize_boolean() {
521 let mut deser = HttpStringDeserializer::new("true");
522 assert!(deser.read_boolean(&BOOLEAN).unwrap());
523
524 let mut deser = HttpStringDeserializer::new("false");
525 assert!(!(deser.read_boolean(&BOOLEAN).unwrap()));
526 }
527
528 #[test]
529 fn test_deserialize_integers() {
530 let mut deser = HttpStringDeserializer::new("42");
531 assert_eq!(deser.read_byte(&BYTE).unwrap(), 42);
532
533 let mut deser = HttpStringDeserializer::new("-123");
534 assert_eq!(deser.read_integer(&INTEGER).unwrap(), -123);
535
536 let mut deser = HttpStringDeserializer::new("9876543210");
537 assert_eq!(deser.read_long(&LONG).unwrap(), 9876543210);
538 }
539
540 #[test]
541 fn test_deserialize_floats() {
542 let mut deser = HttpStringDeserializer::new("3.15");
543 assert!((deser.read_float(&FLOAT).unwrap() - 3.15).abs() < 0.01);
544
545 let mut deser = HttpStringDeserializer::new("NaN");
546 assert!(deser.read_float(&FLOAT).unwrap().is_nan());
547
548 let mut deser = HttpStringDeserializer::new("Infinity");
549 assert_eq!(deser.read_float(&FLOAT).unwrap(), f32::INFINITY);
550 }
551
552 #[test]
553 fn test_deserialize_string() {
554 let mut deser = HttpStringDeserializer::new("hello world");
555 assert_eq!(deser.read_string(&STRING).unwrap(), "hello world");
556 }
557
558 #[test]
559 fn test_deserialize_list() {
560 let mut deser = HttpStringDeserializer::new("a,b,c");
561 let values = vec![
562 deser.read_string(&STRING).unwrap(),
563 deser.read_string(&STRING).unwrap(),
564 deser.read_string(&STRING).unwrap(),
565 ];
566 assert_eq!(values, vec!["a", "b", "c"]);
567 }
568
569 #[test]
570 fn test_deserialize_blob() {
571 let mut deser = HttpStringDeserializer::new("AQIDBA==");
572 let blob = deser.read_blob(&BLOB).unwrap();
573 assert_eq!(blob.as_ref(), &[1, 2, 3, 4]);
574 }
575
576 #[test]
577 fn test_container_size() {
578 let deser = HttpStringDeserializer::new("a,b,c");
579 assert_eq!(deser.container_size(), Some(3));
580
581 let deser = HttpStringDeserializer::new("single");
582 assert_eq!(deser.container_size(), Some(1));
583 }
584
585 #[test]
586 fn test_is_null() {
587 let deser = HttpStringDeserializer::new("");
588 assert!(deser.is_null());
589
590 let deser = HttpStringDeserializer::new("value");
591 assert!(!deser.is_null());
592 }
593
594 #[test]
595 fn test_codec_trait() {
596 use crate::codec::Codec;
597
598 let codec = HttpStringCodec;
599
600 let mut ser = codec.create_serializer();
602 ser.write_string(&STRING, "test").unwrap();
603 let output = ser.finish();
604 assert_eq!(output, "test");
605
606 let input = b"hello";
608 let mut deser = codec.create_deserializer(input);
609 let result = deser.read_string(&STRING).unwrap();
610 assert_eq!(result, "hello");
611 }
612}