settings/intl/
intl_fidl_handler.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::base::{SettingInfo, SettingType};
use crate::handler::base::Request;
use crate::ingress::{request, watch, Scoped};
use crate::job::source::{Error as JobError, ErrorResponder};
use crate::job::Job;

use fidl::endpoints::{ControlHandle, Responder};
use fidl_fuchsia_settings::{
    IntlRequest, IntlSetResponder, IntlSetResult, IntlSettings, IntlWatchResponder,
};

impl From<SettingInfo> for IntlSettings {
    fn from(response: SettingInfo) -> Self {
        if let SettingInfo::Intl(info) = response {
            return info.into();
        }

        panic!("incorrect value sent to intl");
    }
}

impl From<IntlSettings> for Request {
    fn from(settings: IntlSettings) -> Self {
        Request::SetIntlInfo(settings.into())
    }
}

impl TryFrom<IntlRequest> for Job {
    type Error = JobError;
    fn try_from(item: IntlRequest) -> Result<Self, Self::Error> {
        #[allow(unreachable_patterns)]
        match item {
            IntlRequest::Set { settings, responder } => Ok(request::Work::new(
                SettingType::Intl,
                Request::SetIntlInfo(settings.into()),
                responder,
            )
            .into()),
            IntlRequest::Watch { responder } => {
                Ok(watch::Work::new_job(SettingType::Intl, responder))
            }
            _ => {
                tracing::warn!("Received a call to an unsupported API: {:?}", item);
                Err(JobError::Unsupported)
            }
        }
    }
}

impl ErrorResponder for IntlSetResponder {
    fn id(&self) -> &'static str {
        "Intl_Set"
    }

    fn respond(self: Box<Self>, error: fidl_fuchsia_settings::Error) -> Result<(), fidl::Error> {
        self.send(Err(error))
    }
}

impl watch::Responder<IntlSettings, zx::Status> for IntlWatchResponder {
    fn respond(self, response: Result<IntlSettings, zx::Status>) {
        match response {
            Ok(settings) => {
                let _ = self.send(&settings).ok();
            }
            Err(error) => {
                self.control_handle().shutdown_with_epitaph(error);
            }
        }
    }
}

impl request::Responder<Scoped<IntlSetResult>> for IntlSetResponder {
    fn respond(self, Scoped(response): Scoped<IntlSetResult>) {
        let _ = self.send(response).ok();
    }
}

#[cfg(test)]
mod tests {
    use crate::intl::types::{HourCycle, IntlInfo, LocaleId, TemperatureUnit};

    use super::*;

    #[fuchsia::test]
    fn test_request_from_settings_empty() {
        let request = Request::from(IntlSettings::default());

        assert_eq!(
            request,
            Request::SetIntlInfo(IntlInfo {
                locales: None,
                temperature_unit: None,
                time_zone_id: None,
                hour_cycle: None,
            })
        );
    }

    #[fuchsia::test]
    fn test_request_from_settings() {
        const TIME_ZONE_ID: &str = "PDT";

        let intl_settings = IntlSettings {
            locales: Some(vec![fidl_fuchsia_intl::LocaleId { id: "blah".into() }]),
            temperature_unit: Some(fidl_fuchsia_intl::TemperatureUnit::Celsius),
            time_zone_id: Some(fidl_fuchsia_intl::TimeZoneId { id: TIME_ZONE_ID.to_string() }),
            hour_cycle: Some(fidl_fuchsia_settings::HourCycle::H12),
            ..Default::default()
        };

        let request = Request::from(intl_settings);

        assert_eq!(
            request,
            Request::SetIntlInfo(IntlInfo {
                locales: Some(vec![LocaleId { id: "blah".into() }]),
                temperature_unit: Some(TemperatureUnit::Celsius),
                time_zone_id: Some(TIME_ZONE_ID.to_string()),
                hour_cycle: Some(HourCycle::H12),
            })
        );
    }
}