devtools/actors/
environment.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use serde::Serialize;
6use serde_json::{Map, Value};
7
8use crate::StreamId;
9use crate::actor::{Actor, ActorError, ActorRegistry};
10use crate::actors::object::ObjectActorMsg;
11use crate::protocol::ClientRequest;
12
13#[derive(Serialize)]
14#[serde(rename_all = "camelCase")]
15pub enum EnvironmentType {
16    Function,
17    _Block,
18    _Object,
19}
20
21#[derive(Serialize)]
22#[serde(rename_all = "camelCase")]
23pub enum EnvironmentScope {
24    Function,
25    _Global,
26}
27
28#[derive(Serialize)]
29struct EnvironmentBindings {
30    arguments: Vec<Value>,
31    variables: Map<String, Value>,
32}
33
34#[derive(Serialize)]
35#[serde(rename_all = "camelCase")]
36struct EnvironmentFunction {
37    display_name: String,
38}
39
40#[derive(Serialize)]
41#[serde(rename_all = "camelCase")]
42pub struct EnvironmentActorMsg {
43    actor: String,
44    #[serde(rename = "type")]
45    type_: EnvironmentType,
46    scope_kind: EnvironmentScope,
47    #[serde(skip_serializing_if = "Option::is_none")]
48    parent: Option<Box<EnvironmentActorMsg>>,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    bindings: Option<EnvironmentBindings>,
51    /// Should be set if `type_` is `EnvironmentType::Function`
52    #[serde(skip_serializing_if = "Option::is_none")]
53    function: Option<EnvironmentFunction>,
54    /// Should be set if `type_` is `EnvironmentType::Object`
55    #[serde(skip_serializing_if = "Option::is_none")]
56    object: Option<ObjectActorMsg>,
57}
58
59/// Resposible for listing the bindings in an environment and assigning new values to them.
60/// Referenced by `FrameActor` when replying to `getEnvironment` messages.
61/// <https://searchfox.org/firefox-main/source/devtools/server/actors/environment.js>
62pub struct EnvironmentActor {
63    pub name: String,
64    pub parent: Option<String>,
65}
66
67impl Actor for EnvironmentActor {
68    fn name(&self) -> String {
69        self.name.clone()
70    }
71
72    fn handle_message(
73        &self,
74        _request: ClientRequest,
75        _registry: &ActorRegistry,
76        _msg_type: &str,
77        _msg: &Map<String, Value>,
78        _id: StreamId,
79    ) -> Result<(), ActorError> {
80        // TODO: Handle messages.
81        Err(ActorError::UnrecognizedPacketType)
82    }
83}
84
85pub trait EnvironmentToProtocol {
86    fn encode(&self, actors: &ActorRegistry) -> EnvironmentActorMsg;
87}
88
89impl EnvironmentToProtocol for EnvironmentActor {
90    fn encode(&self, actors: &ActorRegistry) -> EnvironmentActorMsg {
91        let parent = self
92            .parent
93            .as_ref()
94            .map(|p| actors.find::<EnvironmentActor>(p))
95            .map(|p| Box::new(p.encode(actors)));
96        // TODO: Change hardcoded values.
97        EnvironmentActorMsg {
98            actor: self.name(),
99            type_: EnvironmentType::Function,
100            scope_kind: EnvironmentScope::Function,
101            parent,
102            bindings: None,
103            function: None,
104            object: None,
105        }
106    }
107}