netstack3_base/
convert.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! General utilities for converting types.
6
7/// Provides functions for converting infallibly between types.
8///
9/// This trait can be implemented on types that allow converting between two
10/// related types. It has two blanket implementations: `()` for identity
11/// conversions, i.e. `Input=Output`, and [`UninstantiableConverter`] as an
12/// uninstantiable type that implements the trait for any input and output.
13pub trait BidirectionalConverter<Input, Output> {
14    /// Converts an instance of `Input` into an instance of `Output`.
15    fn convert(&self, a: Input) -> Output;
16
17    /// Converts an instance of `Output` into an instance of `Input`.
18    fn convert_back(&self, b: Output) -> Input;
19}
20
21impl<I> BidirectionalConverter<I, I> for () {
22    fn convert_back(&self, value: I) -> I {
23        value
24    }
25    fn convert(&self, value: I) -> I {
26        value
27    }
28}
29
30/// A marker trait for [`BidirectionalConverter`] of owned or reference types.
31pub trait OwnedOrRefsBidirectionalConverter<Input, Output>:
32    BidirectionalConverter<Input, Output>
33    + for<'a> BidirectionalConverter<&'a Input, &'a Output>
34    + for<'a> BidirectionalConverter<&'a mut Input, &'a mut Output>
35{
36}
37
38impl<I, O, B> OwnedOrRefsBidirectionalConverter<I, O> for B where
39    B: BidirectionalConverter<I, O>
40        + for<'a> BidirectionalConverter<&'a I, &'a O>
41        + for<'a> BidirectionalConverter<&'a mut I, &'a mut O>
42{
43}
44
45#[cfg(test)]
46mod test {
47    use super::*;
48
49    #[test]
50    fn bidirectional_converter_identity() {
51        let a = ();
52        assert_eq!(a.convert(123), 123);
53        assert_eq!(a.convert_back(123), 123);
54    }
55}