stdto_core/
traits.rs

1#![allow(unused_imports, unused_macros)]
2
3use crate::{
4    enums::{Endian, HexMode},
5    error::*,
6};
7use std::{fmt, io};
8
9use borsh::{BorshDeserialize, BorshSerialize};
10
11#[cfg(feature = "serde")]
12use serde::{de::DeserializeOwned, Serialize};
13
14#[cfg(feature = "bytes")]
15use bincode::Options;
16
17#[cfg(feature = "hash")]
18use digest::{Digest, Output};
19
20#[cfg(feature = "json")]
21use serde_json::Value as JsonValue;
22
23#[cfg(feature = "yaml")]
24use serde_yaml::Value as YamlValue;
25
26#[cfg(feature = "toml")]
27use serde_toml::Value as TomlValue;
28
29macro_rules! serialize {
30    (data: $self:expr, option: $option:expr) => {
31        $option
32            .with_fixint_encoding()
33            .allow_trailing_bytes()
34            .serialize($self)
35            .map_err(Error::Bytes)
36    };
37    (data: $self:expr, writer: $writer:expr, option: $option:expr) => {
38        $option
39            .with_fixint_encoding()
40            .serialize_into($writer, $self)
41            .map_err(Error::Bytes)
42    };
43}
44
45macro_rules! deserialize {
46    (data: $bytes:expr, option: $option:expr) => {
47        $option
48            .with_fixint_encoding()
49            .allow_trailing_bytes()
50            .deserialize($bytes)
51            .map_err(Error::Bytes)
52    };
53    (reader: $reader:expr, option: $option:expr) => {
54        $option
55            .with_fixint_encoding()
56            .allow_trailing_bytes()
57            .deserialize_from($reader)
58            .map_err(Error::Bytes)
59    };
60}
61
62/// # A trait that can convert to a slice of bytes.
63pub trait AsBytes {
64    fn as_byte_slice(&self) -> &[u8];
65    #[inline]
66    fn to_bytes(&self) -> Vec<u8> {
67        self.as_byte_slice().to_vec()
68    }
69    #[inline]
70    fn into_bytes(self) -> Vec<u8>
71    where
72        Self: Sized,
73    {
74        self.to_bytes()
75    }
76    #[inline]
77    fn try_to_bytes_into(&self, mut writer: impl io::Write) -> Result<()> {
78        writer.write_all(self.as_byte_slice()).map_err(Error::Io)
79    }
80    #[inline]
81    fn to_bytes_into(&self, writer: impl io::Write) {
82        self.try_to_bytes_into(writer).unwrap()
83    }
84}
85
86/// implement `AsBytes` for `impl AsRef<[u8]>`
87impl<T: AsRef<[u8]>> AsBytes for T {
88    #[inline]
89    fn as_byte_slice(&self) -> &[u8] {
90        self.as_ref()
91    }
92}
93
94/// # A trait for converting a byte slice to a string.
95pub trait ToStringForBytes: AsBytes {
96    #[inline]
97    fn try_as_str(&self) -> Result<&str> {
98        std::str::from_utf8(self.as_byte_slice()).map_err(Error::Utf8)
99    }
100    #[inline]
101    fn try_to_string(&self) -> Result<String> {
102        self.try_as_str().map(|s| s.to_string())
103    }
104    /// # Safety
105    /// This function is unsafe because it does not check if the bytes are valid UTF-8.
106    #[inline]
107    fn as_str(&self) -> &str {
108        self.try_as_str().unwrap()
109    }
110    /// # Safety
111    /// This function is unsafe because it does not check if the bytes are valid UTF-8.
112    #[inline]
113    fn to_string(&self) -> String {
114        self.try_to_string().unwrap()
115    }
116    #[inline]
117    fn to_string_lossy(&self) -> String {
118        String::from_utf8_lossy(self.as_byte_slice()).to_string()
119    }
120    #[inline]
121    fn try_into_string(self) -> Result<String>
122    where
123        Self: Sized,
124    {
125        self.try_to_string()
126    }
127    /// # Safety
128    /// This function is unsafe because it does not check if the bytes are valid UTF-8.
129    #[inline]
130    fn into_string(self) -> String
131    where
132        Self: Sized,
133    {
134        self.to_string()
135    }
136}
137
138/// implement `AsBytes` for `impl AsBytes`
139impl<T: AsBytes> ToStringForBytes for T {}
140
141#[cfg(feature = "bytes")]
142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143pub struct ToBytesOptions {
144    pub endian: Endian,
145}
146#[cfg(feature = "bytes")]
147impl ToBytesOptions {
148    #[inline]
149    pub const fn default() -> Self {
150        ToBytesOptions {
151            endian: Endian::Little,
152        }
153    }
154}
155
156#[cfg(feature = "bytes")]
157/// # A trait that can de/serialize something with bytes. (default: little endian)
158pub trait ToBytes {
159    const OPTIONS: ToBytesOptions = ToBytesOptions {
160        ..ToBytesOptions::default()
161    };
162
163    /// Serialize to bytes.
164    #[inline]
165    fn try_to_be_bytes(&self) -> Result<Vec<u8>>
166    where
167        Self: Serialize,
168    {
169        serialize!(data: self, option: bincode::options().with_big_endian())
170    }
171    #[inline]
172    fn try_to_le_bytes(&self) -> Result<Vec<u8>>
173    where
174        Self: Serialize,
175    {
176        serialize!(data: self, option: bincode::options().with_little_endian())
177    }
178    #[inline]
179    fn try_to_ne_bytes(&self) -> Result<Vec<u8>>
180    where
181        Self: Serialize,
182    {
183        serialize!(data: self, option: bincode::options().with_native_endian())
184    }
185    #[inline]
186    fn try_to_be_bytes_into(&self, writer: impl io::Write) -> Result<()>
187    where
188        Self: Serialize,
189    {
190        serialize!(data: self, writer: writer, option: bincode::options().with_big_endian())
191    }
192    #[inline]
193    fn try_to_le_bytes_into(&self, writer: impl io::Write) -> Result<()>
194    where
195        Self: Serialize,
196    {
197        serialize!(data: self, writer: writer, option: bincode::options().with_little_endian())
198    }
199    #[inline]
200    fn try_to_ne_bytes_into(&self, writer: impl io::Write) -> Result<()>
201    where
202        Self: Serialize,
203    {
204        serialize!(data: self, writer: writer, option: bincode::options().with_native_endian())
205    }
206    // ---------------------
207    #[inline]
208    fn to_be_bytes(&self) -> Vec<u8>
209    where
210        Self: Serialize,
211    {
212        self.try_to_be_bytes().unwrap()
213    }
214    #[inline]
215    fn to_le_bytes(&self) -> Vec<u8>
216    where
217        Self: Serialize,
218    {
219        self.try_to_le_bytes().unwrap()
220    }
221    #[inline]
222    fn to_ne_bytes(&self) -> Vec<u8>
223    where
224        Self: Serialize,
225    {
226        self.try_to_ne_bytes().unwrap()
227    }
228    #[inline]
229    fn to_be_bytes_into(&self, writer: impl io::Write)
230    where
231        Self: Serialize,
232    {
233        self.try_to_be_bytes_into(writer).unwrap()
234    }
235    #[inline]
236    fn to_le_bytes_into(&self, writer: impl io::Write)
237    where
238        Self: Serialize,
239    {
240        self.try_to_le_bytes_into(writer).unwrap()
241    }
242    #[inline]
243    fn to_ne_bytes_into(&self, writer: impl io::Write)
244    where
245        Self: Serialize,
246    {
247        self.try_to_ne_bytes_into(writer).unwrap()
248    }
249    // ---------------------
250
251    /// Deserialize from bytes.
252    #[inline]
253    fn try_from_be_bytes(bytes: impl AsBytes) -> Result<Self>
254    where
255        Self: DeserializeOwned,
256    {
257        deserialize!(data: bytes.as_byte_slice(), option: bincode::options().with_big_endian())
258    }
259    #[inline]
260    fn try_from_le_bytes(bytes: impl AsBytes) -> Result<Self>
261    where
262        Self: DeserializeOwned,
263    {
264        deserialize!(data: bytes.as_byte_slice(), option: bincode::options().with_little_endian())
265    }
266    #[inline]
267    fn try_from_ne_bytes(bytes: impl AsBytes) -> Result<Self>
268    where
269        Self: DeserializeOwned,
270    {
271        deserialize!(data: bytes.as_byte_slice(), option: bincode::options().with_native_endian())
272    }
273    #[inline]
274    fn try_from_be_bytes_from(reader: impl io::Read) -> Result<Self>
275    where
276        Self: DeserializeOwned,
277    {
278        deserialize!(reader: reader, option: bincode::options().with_big_endian())
279    }
280    #[inline]
281    fn try_from_le_bytes_from(reader: impl io::Read) -> Result<Self>
282    where
283        Self: DeserializeOwned,
284    {
285        deserialize!(reader: reader, option: bincode::options().with_little_endian())
286    }
287    #[inline]
288    fn try_from_ne_bytes_from(reader: impl io::Read) -> Result<Self>
289    where
290        Self: DeserializeOwned,
291    {
292        deserialize!(reader: reader, option: bincode::options().with_native_endian())
293    }
294    // ---------------------
295    #[inline]
296    fn from_be_bytes(bytes: impl AsBytes) -> Self
297    where
298        Self: DeserializeOwned,
299    {
300        Self::try_from_be_bytes(bytes).unwrap()
301    }
302    #[inline]
303    fn from_le_bytes(bytes: impl AsBytes) -> Self
304    where
305        Self: DeserializeOwned,
306    {
307        Self::try_from_le_bytes(bytes).unwrap()
308    }
309    #[inline]
310    fn from_ne_bytes(bytes: impl AsBytes) -> Self
311    where
312        Self: DeserializeOwned,
313    {
314        Self::try_from_ne_bytes(bytes).unwrap()
315    }
316    #[inline]
317    fn from_be_bytes_from(reader: impl io::Read) -> Self
318    where
319        Self: DeserializeOwned,
320    {
321        Self::try_from_be_bytes_from(reader).unwrap()
322    }
323    #[inline]
324    fn from_le_bytes_from(reader: impl io::Read) -> Self
325    where
326        Self: DeserializeOwned,
327    {
328        Self::try_from_le_bytes_from(reader).unwrap()
329    }
330    #[inline]
331    fn from_ne_bytes_from(reader: impl io::Read) -> Self
332    where
333        Self: DeserializeOwned,
334    {
335        Self::try_from_ne_bytes_from(reader).unwrap()
336    }
337
338    // ------------- default endians -------------
339    #[inline]
340    fn try_to_bytes(&self) -> Result<Vec<u8>>
341    where
342        Self: Serialize,
343    {
344        match Self::OPTIONS.endian {
345            Endian::Big => self.try_to_be_bytes(),
346            Endian::Little => self.try_to_le_bytes(),
347            Endian::Native => self.try_to_ne_bytes(),
348        }
349    }
350    #[inline]
351    fn try_to_bytes_into(&self, writer: impl io::Write) -> Result<()>
352    where
353        Self: Serialize,
354    {
355        match Self::OPTIONS.endian {
356            Endian::Big => self.try_to_be_bytes_into(writer),
357            Endian::Little => self.try_to_le_bytes_into(writer),
358            Endian::Native => self.try_to_ne_bytes_into(writer),
359        }
360    }
361    #[inline]
362    fn try_from_bytes(bytes: impl AsBytes) -> Result<Self>
363    where
364        Self: DeserializeOwned,
365    {
366        match Self::OPTIONS.endian {
367            Endian::Big => Self::try_from_be_bytes(bytes),
368            Endian::Little => Self::try_from_le_bytes(bytes),
369            Endian::Native => Self::try_from_ne_bytes(bytes),
370        }
371    }
372    #[inline]
373    fn try_from_bytes_from(reader: impl io::Read) -> Result<Self>
374    where
375        Self: DeserializeOwned,
376    {
377        match Self::OPTIONS.endian {
378            Endian::Big => Self::try_from_be_bytes_from(reader),
379            Endian::Little => Self::try_from_le_bytes_from(reader),
380            Endian::Native => Self::try_from_ne_bytes_from(reader),
381        }
382    }
383    // --------------------------------------------------
384    #[inline]
385    fn to_bytes(&self) -> Vec<u8>
386    where
387        Self: Serialize,
388    {
389        self.try_to_bytes().unwrap()
390    }
391    #[inline]
392    fn to_bytes_into(&self, writer: impl io::Write)
393    where
394        Self: Serialize,
395    {
396        self.try_to_bytes_into(writer).unwrap()
397    }
398    #[inline]
399    fn from_bytes(bytes: impl AsBytes) -> Self
400    where
401        Self: DeserializeOwned,
402    {
403        Self::try_from_bytes(bytes).unwrap()
404    }
405    #[inline]
406    fn from_bytes_from(reader: impl io::Read) -> Self
407    where
408        Self: DeserializeOwned,
409    {
410        Self::try_from_bytes_from(reader).unwrap()
411    }
412
413    // ----------------------------------------------------------------------
414}
415
416#[cfg(feature = "bytes")]
417pub trait ToBorshBytes {
418    /// BorshSerialize to bytes.
419    #[inline]
420    fn try_to_borsh_bytes(&self) -> Result<Vec<u8>>
421    where
422        Self: BorshSerialize,
423    {
424        self.try_to_vec().map_err(Error::Io)
425    }
426    #[inline]
427    fn try_to_borsh_bytes_into(&self, mut writer: impl io::Write) -> Result<()>
428    where
429        Self: BorshSerialize,
430    {
431        self.serialize(&mut writer).map_err(Error::Io)
432    }
433    // ---------------------
434    #[inline]
435    fn to_borsh_bytes(&self) -> Vec<u8>
436    where
437        Self: BorshSerialize,
438    {
439        self.try_to_borsh_bytes().unwrap()
440    }
441    #[inline]
442    fn to_borsh_bytes_into(&self, writer: impl io::Write)
443    where
444        Self: BorshSerialize,
445    {
446        self.try_to_borsh_bytes_into(writer).unwrap()
447    }
448    // ---------------------
449
450    /// BorshDeserialize from bytes.
451    #[inline]
452    fn try_from_borsh_bytes(bytes: impl AsBytes) -> Result<Self>
453    where
454        Self: BorshDeserialize,
455    {
456        BorshDeserialize::try_from_slice(bytes.as_byte_slice()).map_err(Error::Io)
457    }
458    #[inline]
459    fn try_from_borsh_bytes_from(mut reader: impl io::Read) -> Result<Self>
460    where
461        Self: BorshDeserialize,
462    {
463        BorshDeserialize::try_from_reader(&mut reader).map_err(Error::Io)
464    }
465    // ---------------------
466    #[inline]
467    fn from_borsh_bytes(bytes: impl AsBytes) -> Self
468    where
469        Self: BorshDeserialize,
470    {
471        Self::try_from_borsh_bytes(bytes).unwrap()
472    }
473    #[inline]
474    fn from_borsh_bytes_from(reader: impl io::Read) -> Self
475    where
476        Self: BorshDeserialize,
477    {
478        Self::try_from_borsh_bytes_from(reader).unwrap()
479    }
480}
481
482#[cfg(feature = "hash")]
483/// # A trait that can hash bytes.
484pub trait ToHash {
485    #[inline]
486    fn try_to_hash<T: Digest + io::Write>(&self) -> Result<Output<T>>
487    where
488        Self: ToBytes + Serialize,
489    {
490        let mut hasher = T::new();
491        self.try_to_hash_into(&mut hasher)?;
492        Ok(hasher.finalize())
493    }
494    #[inline]
495    fn try_to_hash_into<T: Digest + io::Write>(&self, hasher: &mut T) -> Result<()>
496    where
497        Self: ToBytes + Serialize,
498    {
499        self.try_to_bytes_into(hasher)
500    }
501    #[inline]
502    fn to_hash<T: Digest + io::Write>(&self) -> Output<T>
503    where
504        Self: ToBytes + Serialize,
505    {
506        let mut hasher = T::new();
507        self.to_hash_into(&mut hasher);
508        hasher.finalize()
509    }
510    #[inline]
511    fn to_hash_into<T: Digest + io::Write>(&self, hasher: &mut T)
512    where
513        Self: ToBytes + Serialize,
514    {
515        self.to_bytes_into(hasher)
516    }
517
518    // Borsh
519    #[inline]
520    fn try_to_borsh_hash<T: Digest + io::Write>(&self) -> Result<Output<T>>
521    where
522        Self: ToBorshBytes + BorshSerialize,
523    {
524        let mut hasher = T::new();
525        self.try_to_borsh_hash_into(&mut hasher)?;
526        Ok(hasher.finalize())
527    }
528    #[inline]
529    fn try_to_borsh_hash_into<T: Digest + io::Write>(&self, hasher: &mut T) -> Result<()>
530    where
531        Self: ToBorshBytes + BorshSerialize,
532    {
533        self.try_to_borsh_bytes_into(hasher)
534    }
535    #[inline]
536    fn to_borsh_hash<T: Digest + io::Write>(&self) -> Output<T>
537    where
538        Self: ToBorshBytes + BorshSerialize,
539    {
540        let mut hasher = T::new();
541        self.to_borsh_hash_into(&mut hasher);
542        hasher.finalize()
543    }
544    #[inline]
545    fn to_borsh_hash_into<T: Digest + io::Write>(&self, hasher: &mut T)
546    where
547        Self: ToBorshBytes + BorshSerialize,
548    {
549        self.to_borsh_bytes_into(hasher)
550    }
551}
552
553#[cfg(feature = "json")]
554/// # A trait that can de/encode to/from json.
555pub trait ToJson {
556    // --- JsonValue ----
557    #[inline]
558    fn try_to_json_value(&self) -> Result<JsonValue>
559    where
560        Self: Serialize,
561    {
562        serde_json::to_value(self).map_err(Error::Json)
563    }
564    #[inline]
565    fn try_from_json_value(value: JsonValue) -> Result<Self>
566    where
567        Self: DeserializeOwned,
568    {
569        serde_json::from_value(value).map_err(Error::Json)
570    }
571    // --------------
572    #[inline]
573    fn to_json_value(&self) -> JsonValue
574    where
575        Self: Serialize,
576    {
577        self.try_to_json_value().unwrap()
578    }
579    #[inline]
580    fn from_json_value(value: JsonValue) -> Self
581    where
582        Self: DeserializeOwned,
583    {
584        Self::try_from_json_value(value).unwrap()
585    }
586
587    // --- String ----
588    #[inline]
589    fn try_to_json(&self) -> Result<String>
590    where
591        Self: Serialize,
592    {
593        serde_json::to_string(self).map_err(Error::Json)
594    }
595    #[inline]
596    fn try_to_json_into(&self, writer: impl io::Write) -> Result<()>
597    where
598        Self: Serialize,
599    {
600        serde_json::to_writer(writer, self).map_err(Error::Json)
601    }
602    #[inline]
603    fn try_from_json(json: impl AsBytes) -> Result<Self>
604    where
605        Self: DeserializeOwned,
606    {
607        serde_json::from_slice(json.as_byte_slice()).map_err(Error::Json)
608    }
609    #[inline]
610    fn try_from_json_from(reader: impl io::Read) -> Result<Self>
611    where
612        Self: DeserializeOwned,
613    {
614        serde_json::from_reader(reader).map_err(Error::Json)
615    }
616    // --------------
617    #[inline]
618    fn to_json(&self) -> String
619    where
620        Self: Serialize,
621    {
622        self.try_to_json().unwrap()
623    }
624    #[inline]
625    fn to_json_into(&self, writer: impl io::Write)
626    where
627        Self: Serialize,
628    {
629        self.try_to_json_into(writer).unwrap()
630    }
631    #[inline]
632    fn from_json(json: impl AsBytes) -> Self
633    where
634        Self: DeserializeOwned,
635    {
636        Self::try_from_json(json).unwrap()
637    }
638    #[inline]
639    fn from_json_from(reader: impl io::Read) -> Self
640    where
641        Self: DeserializeOwned,
642    {
643        Self::try_from_json_from(reader).unwrap()
644    }
645    // --------------
646    #[inline]
647    fn try_to_json_pretty(&self) -> Result<String>
648    where
649        Self: Serialize,
650    {
651        serde_json::to_string_pretty(self).map_err(Error::Json)
652    }
653    #[inline]
654    fn try_to_json_pretty_into(&self, writer: impl io::Write) -> Result<()>
655    where
656        Self: Serialize,
657    {
658        serde_json::to_writer_pretty(writer, self).map_err(Error::Json)
659    }
660    // --------------
661    #[inline]
662    fn to_json_pretty(&self) -> String
663    where
664        Self: Serialize,
665    {
666        self.try_to_json_pretty().unwrap()
667    }
668    #[inline]
669    fn to_json_pretty_into(&self, writer: impl io::Write)
670    where
671        Self: Serialize,
672    {
673        self.try_to_json_pretty_into(writer).unwrap()
674    }
675}
676
677#[cfg(feature = "yaml")]
678/// # A trait that can de/encode to/from yaml.
679pub trait ToYaml {
680    // --- YamlValue ----
681    #[inline]
682    fn try_to_yaml_value(&self) -> Result<YamlValue>
683    where
684        Self: Serialize,
685    {
686        serde_yaml::to_value(self).map_err(Error::Yaml)
687    }
688    #[inline]
689    fn try_from_yaml_value(value: YamlValue) -> Result<Self>
690    where
691        Self: DeserializeOwned,
692    {
693        serde_yaml::from_value(value).map_err(Error::Yaml)
694    }
695    // --------------
696    #[inline]
697    fn to_yaml_value(&self) -> YamlValue
698    where
699        Self: Serialize,
700    {
701        self.try_to_yaml_value().unwrap()
702    }
703    #[inline]
704    fn from_yaml_value(value: YamlValue) -> Self
705    where
706        Self: DeserializeOwned,
707    {
708        Self::try_from_yaml_value(value).unwrap()
709    }
710
711    // --- String ----
712    #[inline]
713    fn try_to_yaml(&self) -> Result<String>
714    where
715        Self: Serialize,
716    {
717        serde_yaml::to_string(self).map_err(Error::Yaml)
718    }
719    #[inline]
720    fn try_to_yaml_into(&self, writer: impl io::Write) -> Result<()>
721    where
722        Self: Serialize,
723    {
724        serde_yaml::to_writer(writer, self).map_err(Error::Yaml)
725    }
726    #[inline]
727    fn try_from_yaml(yaml: impl AsBytes) -> Result<Self>
728    where
729        Self: DeserializeOwned,
730    {
731        serde_yaml::from_slice(yaml.as_byte_slice()).map_err(Error::Yaml)
732    }
733    #[inline]
734    fn try_from_yaml_from(reader: impl io::Read) -> Result<Self>
735    where
736        Self: DeserializeOwned,
737    {
738        serde_yaml::from_reader(reader).map_err(Error::Yaml)
739    }
740    // --------------
741    #[inline]
742    fn to_yaml(&self) -> String
743    where
744        Self: Serialize,
745    {
746        self.try_to_yaml().unwrap()
747    }
748    #[inline]
749    fn to_yaml_into(&self, writer: impl io::Write)
750    where
751        Self: Serialize,
752    {
753        self.try_to_yaml_into(writer).unwrap()
754    }
755    #[inline]
756    fn from_yaml(yaml: impl AsBytes) -> Self
757    where
758        Self: DeserializeOwned,
759    {
760        Self::try_from_yaml(yaml).unwrap()
761    }
762    #[inline]
763    fn from_yaml_from(reader: impl io::Read) -> Self
764    where
765        Self: DeserializeOwned,
766    {
767        Self::try_from_yaml_from(reader).unwrap()
768    }
769}
770
771#[cfg(feature = "toml")]
772/// # A trait that can de/encode to/from toml.
773pub trait ToToml {
774    // --- TomlValue ----
775    #[inline]
776    fn try_to_toml_value(&self) -> Result<TomlValue>
777    where
778        Self: Serialize,
779    {
780        TomlValue::try_from(self).map_err(Error::TomlSerialize)
781    }
782    #[inline]
783    fn try_from_toml_value(value: TomlValue) -> Result<Self>
784    where
785        Self: DeserializeOwned,
786    {
787        value.try_into().map_err(Error::TomlDeserialize)
788    }
789    // --------------
790    #[inline]
791    fn to_toml_value(&self) -> TomlValue
792    where
793        Self: Serialize,
794    {
795        self.try_to_toml_value().unwrap()
796    }
797    #[inline]
798    fn from_toml_value(value: TomlValue) -> Self
799    where
800        Self: DeserializeOwned,
801    {
802        Self::try_from_toml_value(value).unwrap()
803    }
804
805    // --- String ----
806    #[inline]
807    fn try_to_toml(&self) -> Result<String>
808    where
809        Self: Serialize,
810    {
811        toml::to_string(self).map_err(Error::TomlSerialize)
812    }
813    /// # Optimized
814    ///
815    /// This function is not well optimized yet.
816    #[inline]
817    fn try_to_toml_into(&self, mut writer: impl io::Write) -> Result<()>
818    where
819        Self: Serialize,
820    {
821        writer
822            .write_all(toml::to_vec(self)?.as_slice())
823            .map_err(Error::Io)
824    }
825    #[inline]
826    fn try_from_toml(toml: impl AsBytes) -> Result<Self>
827    where
828        Self: DeserializeOwned,
829    {
830        toml::from_slice(toml.as_byte_slice()).map_err(Error::TomlDeserialize)
831    }
832    /// # Optimized
833    ///
834    /// This function is not well optimized yet.
835    #[inline]
836    fn try_from_toml_from(mut reader: impl io::Read) -> Result<Self>
837    where
838        Self: DeserializeOwned,
839    {
840        let mut buf = Vec::new();
841        reader.read_to_end(&mut buf)?;
842        toml::from_slice(&buf).map_err(Error::TomlDeserialize)
843    }
844    // --------------
845    #[inline]
846    fn to_toml(&self) -> String
847    where
848        Self: Serialize,
849    {
850        self.try_to_toml().unwrap()
851    }
852    #[inline]
853    fn to_toml_into(&self, writer: impl io::Write)
854    where
855        Self: Serialize,
856    {
857        self.try_to_toml_into(writer).unwrap()
858    }
859    #[inline]
860    fn from_toml(toml: impl AsBytes) -> Self
861    where
862        Self: DeserializeOwned,
863    {
864        Self::try_from_toml(toml).unwrap()
865    }
866    #[inline]
867    fn from_toml_from(reader: impl io::Read) -> Self
868    where
869        Self: DeserializeOwned,
870    {
871        Self::try_from_toml_from(reader).unwrap()
872    }
873    // --------------
874    #[inline]
875    fn try_to_toml_pretty(&self) -> Result<String>
876    where
877        Self: Serialize,
878    {
879        toml::to_string_pretty(self).map_err(Error::TomlSerialize)
880    }
881    /// # Optimized
882    ///
883    /// This function is not well optimized yet.
884    #[inline]
885    fn try_to_toml_pretty_into(&self, mut writer: impl io::Write) -> Result<()>
886    where
887        Self: Serialize,
888    {
889        writer
890            .write_all(toml::to_string_pretty(self)?.as_bytes())
891            .map_err(Error::Io)
892    }
893    // --------------
894    #[inline]
895    fn to_toml_pretty(&self) -> String
896    where
897        Self: Serialize,
898    {
899        self.try_to_toml_pretty().unwrap()
900    }
901    /// # Optimized
902    ///
903    /// This function is not well optimized yet.
904    #[inline]
905    fn to_toml_pretty_into(&self, writer: impl io::Write)
906    where
907        Self: Serialize,
908    {
909        self.try_to_toml_pretty_into(writer).unwrap()
910    }
911}
912
913#[cfg(feature = "hex")]
914/// # A trait that can convert bytes to hex string. (encode/decode)
915pub trait ToHex: AsBytes {
916    #[inline]
917    fn try_to_hex_into_with_mode(&self, mut writer: impl fmt::Write, mode: HexMode) -> Result<()> {
918        if mode.has_0x() {
919            write!(writer, "0x")?;
920        }
921        let is_lower = mode.is_lower();
922        for byte in self.as_byte_slice() {
923            if is_lower {
924                write!(writer, "{:02x}", byte)?;
925            } else {
926                write!(writer, "{:02X}", byte)?;
927            }
928        }
929        Ok(())
930    }
931    #[inline]
932    fn try_to_hex_with_mode(&self, mode: HexMode) -> Result<String> {
933        let mut hex = String::with_capacity(
934            self.as_byte_slice().len() * 2 + if mode.has_0x() { 2 } else { 0 }, //
935        );
936        self.try_to_hex_into_with_mode(&mut hex, mode)?;
937        Ok(hex)
938    }
939    #[inline]
940    fn try_from_hex(hex: impl AsBytes) -> Result<Vec<u8>> {
941        let mut hex = hex.as_byte_slice();
942        if hex.starts_with(&[b'0', b'x']) {
943            hex = &hex[2..];
944        }
945        if hex.len() % 2 != 0 {
946            return Err(Error::OddLength);
947        }
948        let mut bytes = Vec::with_capacity(hex.len() / 2);
949        for i in (0..hex.len()).step_by(2) {
950            let s = std::str::from_utf8(&hex[i..i + 2])?;
951            let byte = u8::from_str_radix(s, 16)?;
952            bytes.push(byte);
953        }
954        Ok(bytes)
955    }
956    #[inline]
957    fn try_from_hex_from(mut reader: impl io::Read) -> Result<Vec<u8>> {
958        let mut double = [0u8; 2];
959        reader.read_exact(&mut double)?;
960
961        let mut v = Vec::new();
962        let mut take_into_v = |double: &mut [u8; 2]| -> Result<()> {
963            let ch = std::str::from_utf8(double)?;
964            let byte = u8::from_str_radix(ch, 16)?;
965            v.push(byte);
966            double[0] = 0;
967            double[1] = 0;
968            Ok(())
969        };
970        if double != [b'0', b'x'] {
971            take_into_v(&mut double)?;
972        }
973        loop {
974            if let Err(e) = reader.read_exact(&mut double) {
975                match e.kind() {
976                    io::ErrorKind::UnexpectedEof => {
977                        if double[0] == 0 {
978                            break;
979                        }
980                        return Err(Error::OddLength);
981                    }
982                    _ => return Err(Error::Io(e)),
983                }
984            }
985            take_into_v(&mut double)?;
986        }
987        Ok(v)
988    }
989    #[inline]
990    fn try_copy_from_hex(&mut self, hex: impl AsBytes) -> Result<usize>
991    where
992        Self: AsMut<[u8]>,
993    {
994        let mut hex = hex.as_byte_slice();
995        if hex.starts_with(&[b'0', b'x']) {
996            hex = &hex[2..];
997        }
998        if hex.len() % 2 != 0 {
999            return Err(Error::OddLength);
1000        }
1001        let hex_bytes_len = hex.len() / 2;
1002        let bytes = self.as_mut();
1003        if hex_bytes_len > bytes.len() {
1004            return Err(Error::OutOfBounds(bytes.len(), hex_bytes_len));
1005        }
1006        for i in (0..hex.len()).step_by(2) {
1007            let s = std::str::from_utf8(&hex[i..i + 2])?;
1008            let byte = u8::from_str_radix(s, 16)?;
1009            bytes[i / 2] = byte;
1010        }
1011        Ok(hex_bytes_len)
1012    }
1013
1014    #[inline]
1015    fn try_to_hex(&self) -> Result<String> {
1016        self.try_to_hex_with_mode(HexMode::Lower)
1017    }
1018    #[inline]
1019    fn try_to_upper_hex(&self) -> Result<String> {
1020        self.try_to_hex_with_mode(HexMode::Upper)
1021    }
1022    #[inline]
1023    fn try_to_hex_with_0x(&self) -> Result<String> {
1024        self.try_to_hex_with_mode(HexMode::Lower0x)
1025    }
1026    #[inline]
1027    fn try_to_upper_hex_with_0x(&self) -> Result<String> {
1028        self.try_to_hex_with_mode(HexMode::Upper0x)
1029    }
1030    #[inline]
1031    fn to_hex(&self) -> String {
1032        self.try_to_hex().unwrap()
1033    }
1034    #[inline]
1035    fn to_upper_hex(&self) -> String {
1036        self.try_to_upper_hex().unwrap()
1037    }
1038    #[inline]
1039    fn to_hex_with_0x(&self) -> String {
1040        self.try_to_hex_with_0x().unwrap()
1041    }
1042    #[inline]
1043    fn to_upper_hex_with_0x(&self) -> String {
1044        self.try_to_upper_hex_with_0x().unwrap()
1045    }
1046
1047    #[inline]
1048    fn try_to_hex_into(&self, writer: impl fmt::Write) -> Result<()> {
1049        self.try_to_hex_into_with_mode(writer, HexMode::Lower)
1050    }
1051    #[inline]
1052    fn try_to_upper_hex_into(&self, writer: impl fmt::Write) -> Result<()> {
1053        self.try_to_hex_into_with_mode(writer, HexMode::Upper)
1054    }
1055    #[inline]
1056    fn try_to_hex_into_with_0x(&self, writer: impl fmt::Write) -> Result<()> {
1057        self.try_to_hex_into_with_mode(writer, HexMode::Lower0x)
1058    }
1059    #[inline]
1060    fn try_to_upper_hex_into_with_0x(&self, writer: impl fmt::Write) -> Result<()> {
1061        self.try_to_hex_into_with_mode(writer, HexMode::Upper0x)
1062    }
1063    #[inline]
1064    fn to_hex_into(&self, writer: impl fmt::Write) {
1065        self.try_to_hex_into(writer).unwrap()
1066    }
1067    #[inline]
1068    fn to_upper_hex_into(&self, writer: impl fmt::Write) {
1069        self.try_to_upper_hex_into(writer).unwrap()
1070    }
1071    #[inline]
1072    fn to_hex_into_with_0x(&self, writer: impl fmt::Write) {
1073        self.try_to_hex_into_with_0x(writer).unwrap()
1074    }
1075    #[inline]
1076    fn to_upper_hex_into_with_0x(&self, writer: impl fmt::Write) {
1077        self.try_to_upper_hex_into_with_0x(writer).unwrap()
1078    }
1079
1080    #[inline]
1081    fn from_hex(hex: impl AsBytes) -> Vec<u8> {
1082        Self::try_from_hex(hex).unwrap()
1083    }
1084    #[inline]
1085    fn from_hex_from(reader: impl io::Read) -> Vec<u8> {
1086        Self::try_from_hex_from(reader).unwrap()
1087    }
1088    #[inline]
1089    fn copy_from_hex(&mut self, hex: impl AsBytes) -> usize
1090    where
1091        Self: AsMut<[u8]>,
1092    {
1093        self.try_copy_from_hex(hex).unwrap()
1094    }
1095}
1096
1097#[cfg(feature = "hex")]
1098/// implement `ToHex` for `impl AsBytes`
1099impl<T: AsBytes> ToHex for T {}
1100
1101#[cfg(test)]
1102mod tests {
1103    use super::*;
1104    use serde::Deserialize;
1105
1106    use sha2::Sha256;
1107    #[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
1108    struct Test {
1109        a: u32,
1110        b: String,
1111        c: [u8; 32],
1112        d: Vec<u8>,
1113    }
1114    impl ToBytes for Test {}
1115    impl ToHash for Test {}
1116    impl ToJson for Test {}
1117    impl ToYaml for Test {}
1118    impl ToToml for Test {}
1119
1120    #[test]
1121    fn test_to_bytes() {
1122        let test = Test {
1123            a: 1,
1124            b: "hello".to_owned(),
1125            c: [0; 32],
1126            d: vec![1, 2, 3],
1127        };
1128        let bytes = test.to_bytes();
1129        let test2 = Test::from_bytes(bytes);
1130        if test != test2 {
1131            panic!("test != test2");
1132        }
1133    }
1134
1135    #[test]
1136    fn test_from_bytes() {
1137        let test = Test {
1138            a: 1,
1139            b: "hello".to_owned(),
1140            c: [0; 32],
1141            d: vec![1, 2, 3],
1142        };
1143        let bytes = test.to_bytes();
1144        let test2 = Test::from_bytes(bytes);
1145        if test != test2 {
1146            panic!("test != test2");
1147        }
1148    }
1149
1150    #[test]
1151    fn test_from_bytes_from() {
1152        let test = Test {
1153            a: 1,
1154            b: "hello".to_owned(),
1155            c: [0; 32],
1156            d: vec![1, 2, 3],
1157        };
1158        let bytes = test.to_bytes();
1159        let mut reader = io::Cursor::new(bytes);
1160        let test2 = Test::from_bytes_from(&mut reader);
1161        if test != test2 {
1162            panic!("test != test2");
1163        }
1164    }
1165
1166    #[test]
1167    fn test_endians() {
1168        let test = Test {
1169            a: 1,
1170            b: "hello".to_owned(),
1171            c: [0; 32],
1172            d: vec![1, 2, 3],
1173        };
1174        let be_bytes = test.to_be_bytes();
1175        let le_bytes = test.to_le_bytes();
1176        assert_ne!(be_bytes, le_bytes);
1177    }
1178
1179    #[test]
1180    fn test_to_bytes_for_ref() {
1181        let s = "Hello world".to_string();
1182        let bytes = s.to_bytes();
1183        let bytes2 = s.as_bytes().to_vec();
1184        let bytes3 = s.into_bytes();
1185        assert_eq!(bytes, bytes2);
1186        assert_eq!(bytes, bytes3);
1187
1188        let arr = [1u8, 2, 3, 4, 5];
1189        let bytes = arr.to_bytes();
1190        let bytes2 = arr.to_vec();
1191        assert_eq!(bytes, bytes2);
1192    }
1193
1194    #[test]
1195    fn test_to_string_for_ref() {
1196        let s = "Hello world".to_string();
1197        let _s2 = s.as_bytes();
1198        let s2 = _s2.as_str();
1199        assert_eq!(s, s2);
1200
1201        let arr = [72, 105, 32, 77, 111, 109];
1202        let s = arr.as_str();
1203        assert_eq!(s, "Hi Mom");
1204
1205        let bytes = s.to_bytes();
1206        let s2 = bytes.to_string();
1207        assert_eq!(s, s2);
1208
1209        let a = arr.to_string();
1210        let b = arr.into_string().into_bytes().to_string();
1211        assert_eq!(a, b);
1212
1213        let arr = [72, 105, 77, 111, 109];
1214        let s1 = arr.into_string();
1215        let bytes = s1.to_bytes();
1216        let s2 = bytes.as_str();
1217        assert_eq!(s1, s2);
1218    }
1219
1220    #[test]
1221    fn test_to_hash() {
1222        let test = Test {
1223            a: 1,
1224            b: "hello".to_owned(),
1225            c: [0; 32],
1226            d: vec![1, 2, 3],
1227        };
1228        let hash: [u8; 32] = test.to_hash::<Sha256>().into();
1229        let want = [
1230            47, 4, 143, 18, 245, 11, 240, 126, 40, 67, 246, 163, 209, 169, 27, 33, 175, 175, 122,
1231            26, 143, 64, 16, 251, 138, 178, 167, 255, 87, 173, 70, 37,
1232        ];
1233        assert_eq!(hash, want);
1234    }
1235
1236    #[test]
1237    fn test_to_hash_into() {
1238        let test = Test {
1239            a: 1,
1240            b: "hello".to_owned(),
1241            c: [0; 32],
1242            d: vec![1, 2, 3],
1243        };
1244        let mut hasher = Sha256::new();
1245        test.to_hash_into(&mut hasher);
1246        let hash: [u8; 32] = hasher.finalize().into();
1247        let want = [
1248            47, 4, 143, 18, 245, 11, 240, 126, 40, 67, 246, 163, 209, 169, 27, 33, 175, 175, 122,
1249            26, 143, 64, 16, 251, 138, 178, 167, 255, 87, 173, 70, 37,
1250        ];
1251        assert_eq!(hash, want);
1252    }
1253
1254    #[test]
1255    fn test_to_json() {
1256        let test = Test {
1257            a: 1,
1258            b: "hello".to_owned(),
1259            c: [0; 32],
1260            d: vec![1, 2, 3],
1261        };
1262        let json = test.to_json();
1263        let test2 = Test::from_json(json);
1264        if test != test2 {
1265            panic!("test != test2");
1266        }
1267    }
1268
1269    #[test]
1270    fn test_to_json_pretty() {
1271        let test = Test {
1272            a: 1,
1273            b: "hello".to_owned(),
1274            c: [0; 32],
1275            d: vec![1, 2, 3],
1276        };
1277        let json = test.to_json_pretty();
1278        let test2 = Test::from_json(json);
1279        if test != test2 {
1280            panic!("test != test2");
1281        }
1282    }
1283
1284    #[test]
1285    fn test_to_yaml() {
1286        let test = Test {
1287            a: 1,
1288            b: "hello".to_owned(),
1289            c: [0; 32],
1290            d: vec![1, 2, 3],
1291        };
1292        let yaml = test.to_yaml();
1293        let test2 = Test::from_yaml(yaml);
1294        if test != test2 {
1295            panic!("test != test2");
1296        }
1297    }
1298
1299    #[test]
1300    fn test_to_toml() {
1301        let test = Test {
1302            a: 1,
1303            b: "hello".to_owned(),
1304            c: [0; 32],
1305            d: vec![1, 2, 3],
1306        };
1307        let json = test.to_toml();
1308        let test2 = Test::from_toml(json);
1309        if test != test2 {
1310            panic!("test != test2");
1311        }
1312    }
1313
1314    #[test]
1315    fn test_to_toml_pretty() {
1316        let test = Test {
1317            a: 1,
1318            b: "hello".to_owned(),
1319            c: [0; 32],
1320            d: vec![1, 2, 3],
1321        };
1322        let json = test.to_toml_pretty();
1323        let test2 = Test::from_toml(json);
1324        if test != test2 {
1325            panic!("test != test2");
1326        }
1327    }
1328    #[test]
1329    fn test_to_hex() {
1330        let bytes = b"hello world";
1331        assert_eq!(bytes.to_hex(), "68656c6c6f20776f726c64");
1332        assert_eq!(bytes.to_upper_hex(), "68656C6C6F20776F726C64");
1333        assert_eq!(bytes.to_hex_with_0x(), "0x68656c6c6f20776f726c64");
1334        assert_eq!(bytes.to_upper_hex_with_0x(), "0x68656C6C6F20776F726C64");
1335    }
1336
1337    #[test]
1338    fn test_to_hex_into() {
1339        let bytes = b"hello world";
1340        let mut hex = String::new();
1341
1342        bytes.to_hex_into(&mut hex);
1343        assert_eq!(hex, "68656c6c6f20776f726c64");
1344        hex.clear();
1345
1346        bytes.to_upper_hex_into(&mut hex);
1347        assert_eq!(hex, "68656C6C6F20776F726C64");
1348        hex.clear();
1349
1350        bytes.to_hex_into_with_0x(&mut hex);
1351        assert_eq!(hex, "0x68656c6c6f20776f726c64");
1352        hex.clear();
1353
1354        bytes.to_upper_hex_into_with_0x(&mut hex);
1355        assert_eq!(hex, "0x68656C6C6F20776F726C64");
1356    }
1357
1358    #[test]
1359    fn test_from_hex() {
1360        let bytes = b"hello world";
1361        assert_eq!(Vec::<u8>::from_hex("68656c6c6f20776f726c64"), bytes);
1362        assert_eq!(Vec::<u8>::from_hex("68656C6C6F20776F726C64"), bytes);
1363        assert_eq!(Vec::<u8>::from_hex("0x68656c6c6f20776f726c64"), bytes);
1364        assert_eq!(Vec::<u8>::from_hex("0x68656C6C6F20776F726C64"), bytes);
1365    }
1366
1367    #[test]
1368    fn test_from_hex_from() {
1369        let bytes = b"hello world";
1370        let mut reader = io::Cursor::new("68656c6c6f20776f726c64");
1371        assert_eq!(Vec::<u8>::from_hex_from(&mut reader), bytes);
1372        reader.set_position(0);
1373        assert_eq!(Vec::<u8>::from_hex_from(&mut reader), bytes);
1374        reader.set_position(0);
1375        assert_eq!(Vec::<u8>::from_hex_from(&mut reader), bytes);
1376        reader.set_position(0);
1377        assert_eq!(Vec::<u8>::from_hex_from(&mut reader), bytes);
1378    }
1379
1380    #[test]
1381    fn test_try_from_hex() {
1382        let bytes = b"hello world";
1383        let hex = bytes.to_hex();
1384        let bytes2 = Vec::<u8>::try_from_hex(hex).unwrap();
1385        assert_eq!(bytes, &bytes2[..]);
1386    }
1387
1388    #[test]
1389    fn test_try_from_hex_from() {
1390        let bytes = b"hello world";
1391        let hex = bytes.to_hex();
1392        let bytes2 = Vec::<u8>::try_from_hex_from(hex.as_bytes()).unwrap();
1393        assert_eq!(bytes, &bytes2[..]);
1394    }
1395
1396    #[test]
1397    fn test_try_copy_from_hex() {
1398        let bytes = b"helloz world";
1399        let mut a = [0u8; 12];
1400        a.try_copy_from_hex(bytes.to_hex()).unwrap();
1401        assert_eq!(bytes, &a[..]);
1402    }
1403}