1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! `SendStr` definition and trait implementations
13 use clone::{Clone, DeepClone};
14 use cmp::{Eq, TotalEq, Ord, TotalOrd, Equiv};
16 use container::Container;
18 use str::{Str, StrSlice};
20 use to_bytes::{IterBytes, Cb};
22 /// A SendStr is a string that can hold either a ~str or a &'static str.
23 /// This can be useful as an optimization when an allocation is sometimes
24 /// needed but the common case is statically known.
28 SendStrStatic(&'static str)
32 /// Returns `true` if this `SendStr` wraps an owned string
34 pub fn is_owned(&self) -> bool {
36 SendStrOwned(_) => true,
37 SendStrStatic(_) => false
41 /// Returns `true` if this `SendStr` wraps an static string
43 pub fn is_static(&self) -> bool {
45 SendStrOwned(_) => false,
46 SendStrStatic(_) => true
51 /// Trait for moving into an `SendStr`
52 pub trait IntoSendStr {
53 /// Moves self into an `SendStr`
54 fn into_send_str(self) -> SendStr;
57 impl IntoSendStr for ~str {
59 fn into_send_str(self) -> SendStr { SendStrOwned(self) }
62 impl IntoSendStr for &'static str {
64 fn into_send_str(self) -> SendStr { SendStrStatic(self) }
67 impl IntoSendStr for SendStr {
69 fn into_send_str(self) -> SendStr { self }
73 Section: String trait impls.
74 `SendStr` should behave like a normal string, so we don't derive.
77 impl ToStr for SendStr {
79 fn to_str(&self) -> ~str { self.as_slice().to_owned() }
84 fn eq(&self, other: &SendStr) -> bool {
85 self.as_slice().equals(&other.as_slice())
89 impl TotalEq for SendStr {
91 fn equals(&self, other: &SendStr) -> bool {
92 self.as_slice().equals(&other.as_slice())
96 impl Ord for SendStr {
98 fn lt(&self, other: &SendStr) -> bool {
99 self.as_slice().lt(&other.as_slice())
103 impl TotalOrd for SendStr {
105 fn cmp(&self, other: &SendStr) -> Ordering {
106 self.as_slice().cmp(&other.as_slice())
110 impl<'self, S: Str> Equiv<S> for SendStr {
112 fn equiv(&self, other: &S) -> bool {
113 self.as_slice().equals(&other.as_slice())
117 impl Str for SendStr {
119 fn as_slice<'r>(&'r self) -> &'r str {
121 SendStrOwned(ref s) => s.as_slice(),
122 // XXX: Borrowchecker doesn't recognize lifetime as static unless prompted
123 // SendStrStatic(s) => s.as_slice()
124 SendStrStatic(s) => {let tmp: &'static str = s; tmp}
129 fn into_owned(self) -> ~str {
131 SendStrOwned(s) => s,
132 SendStrStatic(s) => s.to_owned()
137 impl Container for SendStr {
139 fn len(&self) -> uint { self.as_slice().len() }
142 impl Clone for SendStr {
144 fn clone(&self) -> SendStr {
146 SendStrOwned(ref s) => SendStrOwned(s.to_owned()),
147 SendStrStatic(s) => SendStrStatic(s)
152 impl DeepClone for SendStr {
154 fn deep_clone(&self) -> SendStr {
156 SendStrOwned(ref s) => SendStrOwned(s.to_owned()),
157 SendStrStatic(s) => SendStrStatic(s)
162 impl Default for SendStr {
164 fn default() -> SendStr { SendStrStatic("") }
167 impl IterBytes for SendStr {
169 fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
171 SendStrOwned(ref s) => s.iter_bytes(lsb0, f),
172 SendStrStatic(s) => s.iter_bytes(lsb0, f)
179 use clone::{Clone, DeepClone};
180 use cmp::{TotalEq, Ord, TotalOrd, Equiv};
182 use container::Container;
183 use default::Default;
184 use send_str::{SendStrOwned, SendStrStatic};
189 fn test_send_str_traits() {
190 let s = SendStrStatic("abcde");
191 assert_eq!(s.len(), 5);
192 assert_eq!(s.as_slice(), "abcde");
193 assert_eq!(s.to_str(), ~"abcde");
194 assert!(s.equiv(&@"abcde"));
195 assert!(s.lt(&SendStrOwned(~"bcdef")));
196 assert_eq!(SendStrStatic(""), Default::default());
198 let o = SendStrOwned(~"abcde");
199 assert_eq!(o.len(), 5);
200 assert_eq!(o.as_slice(), "abcde");
201 assert_eq!(o.to_str(), ~"abcde");
202 assert!(o.equiv(&@"abcde"));
203 assert!(o.lt(&SendStrStatic("bcdef")));
204 assert_eq!(SendStrOwned(~""), Default::default());
206 assert_eq!(s.cmp(&o), Equal);
207 assert!(s.equals(&o));
208 assert!(s.equiv(&o));
210 assert_eq!(o.cmp(&s), Equal);
211 assert!(o.equals(&s));
212 assert!(o.equiv(&s));
216 fn test_send_str_methods() {
217 let s = SendStrStatic("abcde");
218 assert!(s.is_static());
219 assert!(!s.is_owned());
221 let o = SendStrOwned(~"abcde");
222 assert!(!o.is_static());
223 assert!(o.is_owned());
227 fn test_send_str_clone() {
228 assert_eq!(SendStrOwned(~"abcde"), SendStrStatic("abcde").clone());
229 assert_eq!(SendStrOwned(~"abcde"), SendStrStatic("abcde").deep_clone());
231 assert_eq!(SendStrOwned(~"abcde"), SendStrOwned(~"abcde").clone());
232 assert_eq!(SendStrOwned(~"abcde"), SendStrOwned(~"abcde").deep_clone());
234 assert_eq!(SendStrStatic("abcde"), SendStrStatic("abcde").clone());
235 assert_eq!(SendStrStatic("abcde"), SendStrStatic("abcde").deep_clone());
237 assert_eq!(SendStrStatic("abcde"), SendStrOwned(~"abcde").clone());
238 assert_eq!(SendStrStatic("abcde"), SendStrOwned(~"abcde").deep_clone());
242 fn test_send_str_into_owned() {
243 assert_eq!(SendStrStatic("abcde").into_owned(), ~"abcde");
244 assert_eq!(SendStrOwned(~"abcde").into_owned(), ~"abcde");
248 fn test_into_send_str() {
249 assert_eq!("abcde".into_send_str(), SendStrStatic("abcde"));
250 assert_eq!((~"abcde").into_send_str(), SendStrStatic("abcde"));
251 assert_eq!("abcde".into_send_str(), SendStrOwned(~"abcde"));
252 assert_eq!((~"abcde").into_send_str(), SendStrOwned(~"abcde"));