1#![cfg_attr(all(not(feature = "std"), feature = "collections"), feature(collections))]
11#![cfg_attr(all(not(feature = "collections"), feature = "alloc"), feature(alloc))]
12#![cfg_attr(not(feature = "std"), no_std)]
13#![doc(html_root_url = "https://docs.charr.xyz/extra-default/")]
14#![deny(warnings)]
15
16#[cfg(all(not(feature = "std"), feature = "collections"))]
17extern crate collections;
18
19#[cfg(all(not(feature = "collections"), feature = "alloc"))]
20extern crate alloc;
21
22pub trait DefaultRef {
24 fn default_ref<'a>() -> &'a Self;
26}
27impl<T: ?Sized> DefaultRef for T
28 where for<'a> &'a T: Default
29{
30 fn default_ref<'a>() -> &'a Self {
31 Default::default()
32 }
33}
34
35#[cfg(feature = "alloc")]
36mod boxed {
37 #[cfg(not(feature = "collections"))]
38 use alloc::boxed::Box;
39 #[cfg(all(not(feature = "std"), feature = "collections"))]
40 use collections::boxed::Box;
41
42 pub trait DefaultBox {
44 fn default_box() -> Box<Self>;
46 }
47 impl<T: ?Sized> DefaultBox for T
48 where Box<T>: Default
49 {
50 fn default_box() -> Box<Self> {
51 Default::default()
52 }
53 }
54}
55#[cfg(feature = "alloc")]
56pub use self::boxed::DefaultBox;
57
58#[cfg(feature = "collections")]
59mod owned {
60 #[cfg(feature = "std")]
61 use std::borrow::Borrow;
62
63 #[cfg(not(feature = "std"))]
64 use collections::borrow::{Borrow, ToOwned};
65
66
67 pub trait DefaultOwned: ToOwned {
69 fn default_owned() -> <Self as ToOwned>::Owned;
71 }
72 impl<O: Default + Borrow<T>, T: ?Sized + ToOwned<Owned = O>> DefaultOwned
73 for T {
74 fn default_owned() -> <Self as ToOwned>::Owned {
75 Default::default()
76 }
77 }
78}
79#[cfg(feature = "collections")]
80pub use self::owned::DefaultOwned;
81
82
83#[cfg(test)]
84mod tests {
85 use super::DefaultRef;
86
87 #[test]
88 fn str_ref() {
89 let s: &str = str::default_ref();
90 assert_eq!(s, "");
91 }
92
93 #[test]
94 fn byte_slice() {
95 let s: &[u8] = <[u8]>::default_ref();
96 assert_eq!(s, &[]);
97 }
98
99 #[test]
100 fn float_slice() {
101 let s: &[f64] = <[f64]>::default_ref();
102 assert_eq!(s, &[]);
103 }
104
105 #[cfg(feature = "alloc")]
106 mod alloc {
107 use super::super::DefaultBox;
108
109 #[cfg(not(feature = "collections"))]
110 use alloc::boxed::Box;
111 #[cfg(all(feature = "collections", not(feature = "std")))]
112 use collections::boxed::Box;
113
114 #[test]
115 fn str_box() {
116 let s: Box<str> = str::default_box();
117 assert_eq!(&*s, "");
118 }
119
120 #[cfg(feature = "alloc")]
121 #[test]
122 fn byte_box() {
123 let s: Box<[u8]> = <[u8]>::default_box();
124 assert_eq!(&*s, &[]);
125 }
126
127 #[cfg(feature = "alloc")]
128 #[test]
129 fn float_box() {
130 let s: Box<[f64]> = <[f64]>::default_box();
131 assert_eq!(&*s, &[]);
132 }
133 }
134
135 #[cfg(feature = "collections")]
136 mod collections {
137 use super::super::DefaultOwned;
138
139 #[cfg(all(feature = "collections", not(feature = "std")))]
140 use collections::{Vec, String};
141
142 #[test]
143 fn string() {
144 let s: String = str::default_owned();
145 assert_eq!(&*s, "");
146 }
147
148 #[test]
149 fn byte_vec() {
150 let s: Vec<u8> = <[u8]>::default_owned();
151 assert_eq!(&*s, &[])
152 }
153
154 #[test]
155 fn float_vec() {
156 let s: Vec<f64> = <[f64]>::default_owned();
157 assert_eq!(&*s, &[]);
158 }
159 }
160}