diff --git a/src/snapshot_middleware/project.rs b/src/snapshot_middleware/project.rs index 471a91d8..72fa3706 100644 --- a/src/snapshot_middleware/project.rs +++ b/src/snapshot_middleware/project.rs @@ -9,7 +9,7 @@ use crate::{ FsErrorKind, }, project::{Project, ProjectNode}, - snapshot::InstanceSnapshot, + snapshot::{InstanceMetadata, InstanceSnapshot}, }; use super::{ @@ -55,10 +55,7 @@ fn snapshot_project_node( node: &ProjectNode, imfs: &mut Imfs, ) -> SnapshotInstanceResult<'static> { - assert!( - node.ignore_unknown_instances.is_none(), - "TODO: Support $ignoreUnknownInstances" - ); + let ignore_unknown_instances = node.ignore_unknown_instances.unwrap_or(node.path.is_none()); let name = Cow::Owned(instance_name.to_owned()); let mut class_name = node @@ -131,7 +128,10 @@ fn snapshot_project_node( Ok(Some(InstanceSnapshot { snapshot_id: None, - metadata: Default::default(), // TODO + metadata: InstanceMetadata { + ignore_unknown_instances, + ..Default::default() // TODO: Fill out remaining metadata + }, name, class_name, properties, diff --git a/src/web/api.rs b/src/web/api.rs index de88c73a..2d7e9a37 100644 --- a/src/web/api.rs +++ b/src/web/api.rs @@ -12,8 +12,8 @@ use crate::{ serve_session::ServeSession, web::{ interface::{ - NotFoundError, ReadResponse, ServerInfoResponse, SubscribeResponse, PROTOCOL_VERSION, - SERVER_VERSION, + Instance, NotFoundError, ReadResponse, ServerInfoResponse, SubscribeResponse, + PROTOCOL_VERSION, SERVER_VERSION, }, util::{json, json_ok}, }, @@ -94,8 +94,8 @@ impl ApiService { let argument = &request.uri().path()["/api/read/".len()..]; let requested_ids: Option> = argument.split(',').map(RbxId::parse_str).collect(); - let _requested_ids = match requested_ids { - Some(id) => id, + let requested_ids = match requested_ids { + Some(ids) => ids, None => { return Box::new(future::ok( Response::builder() @@ -110,7 +110,20 @@ impl ApiService { let message_queue = self.serve_session.message_queue(); let message_cursor = message_queue.cursor(); - let instances = HashMap::new(); // TODO + let tree = self.serve_session.tree(); + let inner_tree = tree.inner(); + + let mut instances = HashMap::new(); + + for id in requested_ids { + if let Some(instance) = inner_tree.get_instance(id) { + instances.insert(id, Instance::from_rbx_instance(instance)); + + for descendant in inner_tree.descendants(id) { + instances.insert(descendant.get_id(), Instance::from_rbx_instance(descendant)); + } + } + } json_ok(ReadResponse { session_id: self.serve_session.session_id(), diff --git a/src/web/interface.rs b/src/web/interface.rs index 162f9395..1bc6c117 100644 --- a/src/web/interface.rs +++ b/src/web/interface.rs @@ -1,8 +1,11 @@ //! Defines all the structs needed to interact with the Rojo Serve API. -use std::collections::{HashMap, HashSet}; +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, +}; -use rbx_dom_weak::RbxId; +use rbx_dom_weak::{RbxId, RbxInstance, RbxValue}; use serde::{Deserialize, Serialize}; use crate::session_id::SessionId; @@ -17,9 +20,42 @@ pub const PROTOCOL_VERSION: u64 = 3; #[derive(Debug, Serialize, Deserialize)] pub struct SubscribeMessage; -// TODO #[derive(Debug, Serialize, Deserialize)] -pub struct Instance; +#[serde(rename_all = "camelCase")] +pub struct InstanceMetadata { + pub ignore_unknown_instances: bool, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Instance<'a> { + pub name: Cow<'a, str>, + pub class_name: Cow<'a, str>, + pub properties: Cow<'a, HashMap>, + pub children: Cow<'a, [RbxId]>, + pub metadata: Option, +} + +impl<'a> Instance<'a> { + pub fn from_rbx_instance(source: &RbxInstance) -> Instance<'_> { + // TODO: This is a hack! + let metadata = if source.class_name == "DataModel" { + Some(InstanceMetadata { + ignore_unknown_instances: true, + }) + } else { + None + }; + + Instance { + name: Cow::Borrowed(&source.name), + class_name: Cow::Borrowed(&source.class_name), + properties: Cow::Borrowed(&source.properties), + children: Cow::Borrowed(source.get_children_ids()), + metadata, + } + } +} /// Response body from /api/rojo #[derive(Debug, Serialize, Deserialize)] @@ -35,10 +71,10 @@ pub struct ServerInfoResponse { /// Response body from /api/read/{id} #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct ReadResponse { +pub struct ReadResponse<'a> { pub session_id: SessionId, pub message_cursor: u32, - pub instances: HashMap, + pub instances: HashMap>, } /// Response body from /api/subscribe/{cursor}