1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use crate::{check_string_length, Error}; use std::fmt::Write; #[derive(Clone, Copy, Debug)] pub enum FieldValue<'a> { Float(f64), Integer(i64), UInteger(u64), String(&'a str), Boolean(bool), } impl FieldValue<'_> { pub fn to_writer<W>(&self, mut writer: W) -> Result<(), Error> where W: Write, { match self { FieldValue::Float(v) => write!(writer, "{}", v)?, FieldValue::Integer(v) => write!(writer, "{}i", v)?, FieldValue::UInteger(v) => write!(writer, "{}u", v)?, FieldValue::String(v) => { check_string_length(v)?; writer.write_char('"')?; for c in v.chars() { match c { '\n' => return Err(Error::Newline), '"' => writer.write_str(r#"\""#)?, '\\' => writer.write_str(r#"\\"#)?, _ => writer.write_char(c)?, } } writer.write_char('"')?; } FieldValue::Boolean(v) => { if *v { write!(writer, "true")? } else { write!(writer, "false")? } } } Ok(()) } } #[cfg(test)] mod tests { use super::FieldValue; fn check(field_value: FieldValue, expected: &str) { let mut string = String::new(); field_value.to_writer(&mut string).unwrap(); assert_eq!(string, expected); } #[test] fn test_float() { check(FieldValue::Float(1.), "1"); check( FieldValue::Float(-1.234456e+78), "-1234456000000000000000000000000000000000000000000000000000000000000000000000000", ); } #[test] fn test_integer() { check(FieldValue::Integer(1), "1i"); check(FieldValue::Integer(12485903), "12485903i"); check(FieldValue::Integer(-12485903), "-12485903i"); } #[test] fn test_uinteger() { check(FieldValue::UInteger(1), "1u"); check(FieldValue::UInteger(12485903), "12485903u"); } #[test] fn test_string() { check( FieldValue::String(r#"this is a string"#), r#""this is a string""#, ); check( FieldValue::String(r#""string" within a string"#), r#""\"string\" within a string""#, ); check( FieldValue::String(r#""\"string\" within a string""#), r#""\"\\\"string\\\" within a string\"""#, ); } #[test] fn test_boolean() { check(FieldValue::Boolean(true), "true"); check(FieldValue::Boolean(false), "false"); } }