Skip to main content

bt_hfp/call/
number.rs

1// Copyright 2021 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/// The fuchsia.bluetooth.hfp library representation of a Number.
6pub type FidlNumber = String;
7/// A phone number.  Clients should generally use `as_non_at_string` and
8/// `from_non_at_string` to work with these, which add and remove delimiting
9/// quotes.  As AT commands require these quotes to be in place around numbers,
10/// when generating and parsing AT commands, clients should use `from_at_string`
11/// and `as_at_string`, which maintain the quotes.
12#[derive(Debug, Clone, PartialEq, Hash, Default, Eq)]
13pub struct Number(String);
14
15impl Number {
16    /// Format value indicating no changes on the number presentation are required.
17    /// See HFP v1.8, Section 4.34.2.
18    const NUMBER_FORMAT: i64 = 129;
19
20    /// Returns the numeric representation of the Number's format as specified in HFP v1.8,
21    /// Section 4.34.2.
22    pub fn type_(&self) -> i64 {
23        Number::NUMBER_FORMAT
24    }
25
26    /// Converts the Number to a String, stripping quotes from the beginning and end.
27    pub fn to_non_at_string(&self) -> String {
28        if self.0.len() >= 2 && self.0.starts_with("\"") && self.0.ends_with("\"") {
29            let string = self.0.clone();
30            let mut chars = string.chars();
31            let _front_must_exist = chars.next();
32            let _back_must_exist = chars.next_back();
33            String::from(chars.as_str())
34        } else {
35            self.0.clone()
36        }
37    }
38
39    /// Converts the Number to a String to be used in AT commands, leaving the delimiting quotes in
40    /// place.
41    pub fn to_at_string(&self) -> String {
42        self.0.clone()
43    }
44
45    /// Converts a String to a Number, adding delimiting quotes.
46    pub fn from_non_at_string(s: &str) -> Self {
47        // Phone numbers must be enclosed in double quotes
48        let inner = if s.starts_with("\"") && s.ends_with("\"") {
49            s.to_string()
50        } else {
51            format!("\"{}\"", s)
52        };
53        Self(inner)
54    }
55
56    /// Converts a String to a Number, from an AT command, leaving the delimiting quotes in place.
57    pub fn from_at_string(s: &str) -> Self {
58        Self(String::from(s))
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65
66    #[fuchsia::test]
67    fn number_type_in_valid_range() {
68        let number = Number(String::from("\"1234567\""));
69        // type values must be in range 128-175.
70        assert!(number.type_() >= 128);
71        assert!(number.type_() <= 175);
72    }
73
74    #[fuchsia::test]
75    fn number_str_delimiters() {
76        // Convert str to Number
77        {
78            let actual_number = Number::from_non_at_string("1234567");
79            let expected_number = Number(String::from("\"1234567\""));
80            assert_eq!(actual_number, expected_number);
81        }
82
83        // Convert Number to str
84        {
85            let actual_string = Number(String::from("\"1234567\"")).to_non_at_string();
86            let expected_string = String::from("1234567");
87            assert_eq!(actual_string, expected_string);
88        }
89
90        // Convert str to Number with redundant quotes
91        {
92            let actual_number = Number::from_non_at_string("\"1234567\"");
93            let expected_number = Number(String::from("\"1234567\""));
94            assert_eq!(actual_number, expected_number);
95        }
96
97        // Convert AT command str to Number
98        {
99            let actual_number = Number::from_at_string("\"1234567\"");
100            let expected_number = Number(String::from("\"1234567\""));
101            assert_eq!(actual_number, expected_number);
102        }
103
104        // Convert Number to AT command str
105        {
106            let actual_string = Number(String::from("\"1234567\"")).to_at_string();
107            let expected_string = String::from("\"1234567\"");
108            assert_eq!(actual_string, expected_string);
109        }
110    }
111}