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
// 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 super::facade::NetstackFacade;
use crate::common_utils::common::parse_u64_identifier;
use crate::server::Facade;
use anyhow::Error;
use async_trait::async_trait;
use serde_json::{to_value, Value};

enum NetstackMethod<'a> {
    DisableInterface,
    EnableInterface,
    GetIpv6Addresses,
    GetLinkLocalIpv6Addresses,
    ListInterfaces,
    GetNetstackVersion,
    SetUserNetstackVersion,
    Undefined(&'a str),
}

impl NetstackMethod<'_> {
    pub fn from_str(method: &str) -> NetstackMethod<'_> {
        match method {
            "DisableInterface" => NetstackMethod::DisableInterface,
            "EnableInterface" => NetstackMethod::EnableInterface,
            "GetIpv6Addresses" => NetstackMethod::GetIpv6Addresses,
            "GetLinkLocalIpv6Addresses" => NetstackMethod::GetLinkLocalIpv6Addresses,
            "ListInterfaces" => NetstackMethod::ListInterfaces,
            "GetNetstackVersion" => NetstackMethod::GetNetstackVersion,
            "SetUserNetstackVersion" => NetstackMethod::SetUserNetstackVersion,
            method => NetstackMethod::Undefined(method),
        }
    }
}

#[async_trait(?Send)]
impl Facade for NetstackFacade {
    async fn handle_request(&self, method: String, args: Value) -> Result<Value, Error> {
        match NetstackMethod::from_str(&method) {
            NetstackMethod::ListInterfaces => {
                let result = self.list_interfaces().await?;
                to_value(result).map_err(Into::into)
            }
            NetstackMethod::GetIpv6Addresses => {
                let result = self.get_ipv6_addresses().await?;
                to_value(result).map_err(Into::into)
            }
            NetstackMethod::GetLinkLocalIpv6Addresses => {
                let result = self.get_link_local_ipv6_addresses().await?;
                to_value(result).map_err(Into::into)
            }
            NetstackMethod::EnableInterface => {
                let identifier = parse_u64_identifier(args)?;
                let result = self.enable_interface(identifier).await?;
                to_value(result).map_err(Into::into)
            }
            NetstackMethod::DisableInterface => {
                let identifier = parse_u64_identifier(args)?;
                let result = self.disable_interface(identifier).await?;
                to_value(result).map_err(Into::into)
            }
            NetstackMethod::GetNetstackVersion => {
                let result = self.get_netstack_version().await?;
                to_value(result).map_err(Into::into)
            }
            NetstackMethod::SetUserNetstackVersion => {
                let version = args.try_into()?;
                let result = self.set_user_netstack_version(version).await?;
                to_value(result).map_err(Into::into)
            }
            NetstackMethod::Undefined(method) => {
                Err(anyhow!("invalid Netstack method: {}", method))
            }
        }
    }
}