1use std::convert::{From, Into};
2use std::fmt;
3use std::result::Result as StdResult;
4use std::str::from_utf8;
5
6use protocol::OpCode;
7use result::Result;
8
9use self::Message::*;
10
11#[derive(Debug, Eq, PartialEq, Clone)]
13pub enum Message {
14 Text(String),
16 Binary(Vec<u8>),
18}
19
20impl Message {
21 pub fn text<S>(string: S) -> Message
23 where
24 S: Into<String>,
25 {
26 Message::Text(string.into())
27 }
28
29 pub fn binary<B>(bin: B) -> Message
31 where
32 B: Into<Vec<u8>>,
33 {
34 Message::Binary(bin.into())
35 }
36
37 pub fn is_text(&self) -> bool {
39 match *self {
40 Text(_) => true,
41 Binary(_) => false,
42 }
43 }
44
45 pub fn is_binary(&self) -> bool {
47 match *self {
48 Text(_) => false,
49 Binary(_) => true,
50 }
51 }
52
53 pub fn len(&self) -> usize {
55 match *self {
56 Text(ref string) => string.len(),
57 Binary(ref data) => data.len(),
58 }
59 }
60
61 pub fn is_empty(&self) -> bool {
64 match *self {
65 Text(ref string) => string.is_empty(),
66 Binary(ref data) => data.is_empty(),
67 }
68 }
69
70 #[doc(hidden)]
71 pub fn opcode(&self) -> OpCode {
72 match *self {
73 Text(_) => OpCode::Text,
74 Binary(_) => OpCode::Binary,
75 }
76 }
77
78 pub fn into_data(self) -> Vec<u8> {
80 match self {
81 Text(string) => string.into_bytes(),
82 Binary(data) => data,
83 }
84 }
85
86 pub fn into_text(self) -> Result<String> {
88 match self {
89 Text(string) => Ok(string),
90 Binary(data) => Ok(String::from_utf8(data).map_err(|err| err.utf8_error())?),
91 }
92 }
93
94 pub fn as_text(&self) -> Result<&str> {
97 match *self {
98 Text(ref string) => Ok(string),
99 Binary(ref data) => Ok(from_utf8(data)?),
100 }
101 }
102}
103
104impl From<String> for Message {
105 fn from(string: String) -> Message {
106 Message::text(string)
107 }
108}
109
110impl<'s> From<&'s str> for Message {
111 fn from(string: &'s str) -> Message {
112 Message::text(string)
113 }
114}
115
116impl<'b> From<&'b [u8]> for Message {
117 fn from(data: &'b [u8]) -> Message {
118 Message::binary(data)
119 }
120}
121
122impl From<Vec<u8>> for Message {
123 fn from(data: Vec<u8>) -> Message {
124 Message::binary(data)
125 }
126}
127
128impl fmt::Display for Message {
129 fn fmt(&self, f: &mut fmt::Formatter) -> StdResult<(), fmt::Error> {
130 if let Ok(string) = self.as_text() {
131 write!(f, "{}", string)
132 } else {
133 write!(f, "Binary Data<length={}>", self.len())
134 }
135 }
136}
137
138mod test {
139 #![allow(unused_imports, unused_variables, dead_code)]
140 use super::*;
141
142 #[test]
143 fn display() {
144 let t = Message::text(format!("test"));
145 assert_eq!(t.to_string(), "test".to_owned());
146
147 let bin = Message::binary(vec![0, 1, 3, 4, 241]);
148 assert_eq!(bin.to_string(), "Binary Data<length=5>".to_owned());
149 }
150
151 #[test]
152 fn binary_convert() {
153 let bin = [6u8, 7, 8, 9, 10, 241];
154 let msg = Message::from(&bin[..]);
155 assert!(msg.is_binary());
156 assert!(msg.into_text().is_err());
157 }
158
159 #[test]
160 fn binary_convert_vec() {
161 let bin = vec![6u8, 7, 8, 9, 10, 241];
162 let msg = Message::from(bin);
163 assert!(msg.is_binary());
164 assert!(msg.into_text().is_err());
165 }
166
167 #[test]
168 fn text_convert() {
169 let s = "kiwotsukete";
170 let msg = Message::from(s);
171 assert!(msg.is_text());
172 }
173}