1#![warn(missing_docs, trivial_numeric_casts, unused_extern_crates, unused_import_braces, unused_qualifications,
2 unused_results)]
3
4extern crate ascii;
20
21mod pascal_str;
22mod pascal_string;
23
24pub use pascal_str::{Chars, CharsMut, Lines, PascalStr};
25pub use pascal_string::{IntoChars, PascalString, PascalStringAppendError, PascalStringCreateError, AsciiError};
26use std::u8;
27
28const PASCAL_STRING_BUF_SIZE: usize = u8::MAX as usize;
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33 use ascii::*;
34 use std::borrow::Cow;
35 use std::ffi::{CStr, CString};
36 use std::iter::IntoIterator;
37
38 #[test]
39 fn test_string_creation() {
40 let test = "Hello, my world!".to_owned();
41 let test_pascal = PascalString::from(&test).unwrap();
42 assert_eq!(&test, test_pascal.as_str());
43
44 let too_many_bytes = vec![12u8; 256];
45 assert!(match PascalString::from(&too_many_bytes) {
46 Err(PascalStringCreateError::InputTooLong) => true,
47 _ => false
48 });
49 }
50
51 #[test]
52 fn test_character_append() {
53 let mut string = PascalString::new();
54 assert!(string.try_push('h').is_ok());
55 string.push('e');
56 string.push(76u8);
57 string.push('l');
58 string.push(AsciiChar::L);
59 string.push('o');
60 string.push(AsciiChar::Null);
61
62 assert_eq!(string.as_str(), "heLlLo\0");
63 }
64
65 #[test]
66 fn test_string_append() {
67 let mut string = PascalString::new();
68 string.push_str("Hola, ");
69 string.push_str("Senor!");
70 assert_eq!(string.as_str(), "Hola, Senor!");
71 }
72
73 #[test]
74 fn test_string_indexing_and_char_iteration() {
75 {
76 let string = PascalString::from("q").unwrap();
77 assert_eq!(string[0u8], AsciiChar::q);
78 }
79
80 {
81 let string2 = PascalString::from("WASD").unwrap();
82 {
83 let mut chars_iter = string2.chars();
84 assert_eq!(chars_iter.next(), Some(&AsciiChar::W));
85 assert_eq!(chars_iter.next(), Some(&AsciiChar::A));
86 assert_eq!(chars_iter.next(), Some(&AsciiChar::S));
87 assert_eq!(chars_iter.next(), Some(&AsciiChar::D));
88 assert_eq!(chars_iter.next(), None);
89 }
90
91 let mut into_chars = string2.into_iter();
92 assert_eq!(into_chars.next(), Some(AsciiChar::W));
93 assert_eq!(into_chars.next(), Some(AsciiChar::A));
94 assert_eq!(into_chars.next(), Some(AsciiChar::S));
95 assert_eq!(into_chars.next(), Some(AsciiChar::D));
96 assert_eq!(into_chars.next(), None);
97 }
98 }
99
100 #[test]
101 fn test_lines_iteration() {
102 let string = "hello\n,\nmy\ndarling".to_string();
103 let pstring = PascalString::from(&string).unwrap();
104 for (s0, s1) in pstring.lines().zip(string.split_whitespace()) {
105 assert_eq!(s0.as_str(), s1);
106 }
107 }
108
109 #[test]
110 fn test_as_cstr() {
111 {
112 let msg = "I am your favourite cookie monster >:-)\0";
113 let pstr = PascalString::from(&msg).unwrap();
114 let cstr = CStr::from_bytes_with_nul(msg.as_bytes()).unwrap();
115 let pstr_as_cstr = pstr.as_cstr().unwrap();
116 assert!(match pstr_as_cstr {
117 Cow::Borrowed(_) => true,
118 _ => false
119 });
120 assert_eq!(&*pstr_as_cstr, cstr);
121 }
122
123 {
124 let oversized = ['l'; 255];
125 let string_oversized = {
126 let mut s = String::new();
127 for i in 0..oversized.len() {
128 s.push(oversized[i]);
129 }
130 s
131 };
132 let pstr_oversized = PascalString::from_fixed_ascii_array(255, oversized).unwrap();
133 let cstr_from_pstr_oversized = pstr_oversized.as_cstr().unwrap();
134 let cstr_from_string_oversized = CString::new(string_oversized).unwrap();
135 assert!(match cstr_from_pstr_oversized {
136 Cow::Owned(_) => true,
137 _ => false
138 });
139 assert_eq!(cstr_from_pstr_oversized.into_owned(), cstr_from_string_oversized);
140 }
141
142 {
143 let has_interior_null = "lol\0hi";
144 let pstr = PascalString::from(&has_interior_null).unwrap();
145 let err = match pstr.as_cstr() {
146 Err(err) => err,
147 _ => panic!("incorrect result")
148 };
149 assert_eq!(err.interior_null_index(), 3);
150 }
151 }
152}