1use crate::client::Client;
2use crate::to_string;
3use ureq::{Error, Response};
4use serde::{Deserialize, Deserializer, de};
5use serde_json::Value;
6
7fn to_roaming<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Roaming, D::Error> {
8 Ok(match Value::deserialize(deserializer)? {
9 Value::String(s) => Roaming {
10 roaming_country_code: "".to_string(),
11 roaming_network_code: "".to_string(),
12 roaming_network_name: "".to_string(),
13 status: s,
14 },
15 _ => return Err(de::Error::custom("wrong type"))
16 })
17}
18
19#[derive(Deserialize)]
20pub struct CallingNameDelivery {
21 pub code: String,
22 pub name: String,
23 pub number: String,
24 pub success: String,
25}
26
27#[derive(Deserialize)]
28pub struct Carrier {
29 pub country: String,
30 pub name: String,
31 pub network_code: String,
32 pub network_type: String,
33}
34
35#[derive(Deserialize)]
36pub struct NumberFormat {
37 pub national: String,
38 pub carrier: String,
39 pub country_code: String,
40 pub country_iso: String,
41 pub country_name: String,
42 pub international: String,
43 pub international_formatted: String,
44 pub network_type: String,
45 pub success: bool,
46}
47
48#[derive(Deserialize)]
49pub struct HomeLocationRegister {
50 pub country_code: String,
51 pub country_code_iso3: Option<String>,
52 pub country_name: String,
53 pub country_prefix: String,
54 pub current_carrier: Carrier,
55 pub gsm_code: String,
56 pub gsm_message: String,
57 pub international_format_number: String,
58 pub international_formatted: String,
59 #[serde(deserialize_with = "to_string")]
60 pub lookup_outcome: String,
61 pub lookup_outcome_message: String,
62 pub national_format_number: String,
63 pub original_carrier: Carrier,
64 pub ported: String,
65 pub reachable: String,
66 #[serde(deserialize_with = "to_roaming")]
67 pub roaming: Roaming,
68 pub status: bool,
69 pub status_message: String,
70 pub valid_number: String,
71}
72
73#[derive(Deserialize)]
74pub struct Mnp {
75 pub country: String,
76 pub international_formatted: String,
77 #[serde(rename = "isPorted")]
78 pub is_ported: bool,
79 pub mccmnc: String,
80 pub national_format: String,
81 pub network: String,
82 pub number: String,
83}
84
85#[derive(Deserialize)]
86pub struct MobileNumberPortability {
87 pub code: u16,
88 pub mnp: Mnp,
89 pub price: f64,
90 pub success: bool,
91}
92
93pub struct Roaming {
94 pub roaming_country_code: String,
95 pub roaming_network_code: String,
96 pub roaming_network_name: String,
97 pub status: String,
98}
99
100pub struct LookupParams {
101 pub number: String,
102}
103
104pub struct Lookup {
105 client: Client
106}
107
108impl Lookup {
109 pub fn new(client: Client) -> Self {
110 Lookup {
111 client,
112 }
113 }
114
115 fn post(&self, params: LookupParams, type_: &str, json: bool) -> Result<Response, Error> {
116 let req = self.client.request("POST", "lookup").clone();
117 let res = req.send_form(&[
118 ("json", self.client.bool_to_string(json)),
119 ("number", &*params.number),
120 ("type", type_),
121 ])?;
122
123 Ok(res)
124 }
125
126 pub fn cnam(&self, params: LookupParams) -> Result<CallingNameDelivery, Error> {
127 Ok(self.post(params, "cnam", false).unwrap().into_json::<CallingNameDelivery>()?)
128 }
129
130 pub fn format(&self, params: LookupParams) -> Result<NumberFormat, Error> {
131 Ok(self.post(params, "format", false).unwrap().into_json::<NumberFormat>()?)
132 }
133
134 pub fn hlr(&self, params: LookupParams) -> Result<HomeLocationRegister, Error> {
135 Ok(self.post(params, "hlr", false).unwrap().into_json::<HomeLocationRegister>()?)
136 }
137
138 pub fn mnp_text(&self, params: LookupParams) -> Result<String, Error> {
139 Ok(self.post(params, "mnp", false).unwrap().into_string()?)
140 }
141
142 pub fn mnp_json(&self, params: LookupParams) -> Result<MobileNumberPortability, Error> {
143 Ok(self.post(params, "mnp", true).unwrap().into_json::<MobileNumberPortability>()?)
144 }
145}