devtools/actors/
property_iterator.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 std::collections::HashMap;
6
7use devtools_traits::PropertyDescriptor;
8use malloc_size_of_derive::MallocSizeOf;
9use serde::Serialize;
10use serde_json::{Map, Value};
11
12use crate::StreamId;
13use crate::actor::{Actor, ActorError, ActorRegistry};
14use crate::actors::object::ObjectPropertyDescriptor;
15use crate::protocol::ClientRequest;
16
17#[derive(Serialize)]
18#[serde(rename_all = "camelCase")]
19struct SliceReply {
20    from: String,
21    own_properties: HashMap<String, ObjectPropertyDescriptor>,
22}
23
24#[derive(MallocSizeOf)]
25pub(crate) struct PropertyIteratorActor {
26    name: String,
27    properties: Vec<PropertyDescriptor>,
28}
29
30impl PropertyIteratorActor {
31    pub fn register(registry: &ActorRegistry, properties: Vec<PropertyDescriptor>) -> String {
32        let name = registry.new_name::<Self>();
33        let actor = Self {
34            name: name.clone(),
35            properties,
36        };
37        registry.register::<Self>(actor);
38        name
39    }
40
41    pub fn count(&self) -> u32 {
42        self.properties.len() as u32
43    }
44}
45
46impl Actor for PropertyIteratorActor {
47    fn name(&self) -> String {
48        self.name.clone()
49    }
50
51    fn handle_message(
52        &self,
53        request: ClientRequest,
54        registry: &ActorRegistry,
55        msg_type: &str,
56        msg: &Map<String, Value>,
57        _id: StreamId,
58    ) -> Result<(), ActorError> {
59        match msg_type {
60            "slice" => {
61                let start = msg.get("start").and_then(|v| v.as_u64()).unwrap_or(0) as usize;
62                let count = msg
63                    .get("count")
64                    .and_then(|v| v.as_u64())
65                    .unwrap_or(self.properties.len() as u64) as usize;
66
67                let mut own_properties = HashMap::new();
68                for prop in self.properties.iter().skip(start).take(count) {
69                    own_properties.insert(
70                        prop.name.clone(),
71                        ObjectPropertyDescriptor::from_property_descriptor(registry, prop),
72                    );
73                }
74
75                let reply = SliceReply {
76                    from: self.name(),
77                    own_properties,
78                };
79                request.reply_final(&reply)?
80            },
81            _ => return Err(ActorError::UnrecognizedPacketType),
82        }
83        Ok(())
84    }
85}