Expose tree in API, with hacks to make initial sync-in work sort of

This commit is contained in:
Lucien Greathouse
2019-09-10 15:39:50 -07:00
parent 6a786f18e6
commit e6ba6203bb
3 changed files with 66 additions and 17 deletions

View File

@@ -9,7 +9,7 @@ use crate::{
FsErrorKind, FsErrorKind,
}, },
project::{Project, ProjectNode}, project::{Project, ProjectNode},
snapshot::InstanceSnapshot, snapshot::{InstanceMetadata, InstanceSnapshot},
}; };
use super::{ use super::{
@@ -55,10 +55,7 @@ fn snapshot_project_node<F: ImfsFetcher>(
node: &ProjectNode, node: &ProjectNode,
imfs: &mut Imfs<F>, imfs: &mut Imfs<F>,
) -> SnapshotInstanceResult<'static> { ) -> SnapshotInstanceResult<'static> {
assert!( let ignore_unknown_instances = node.ignore_unknown_instances.unwrap_or(node.path.is_none());
node.ignore_unknown_instances.is_none(),
"TODO: Support $ignoreUnknownInstances"
);
let name = Cow::Owned(instance_name.to_owned()); let name = Cow::Owned(instance_name.to_owned());
let mut class_name = node let mut class_name = node
@@ -131,7 +128,10 @@ fn snapshot_project_node<F: ImfsFetcher>(
Ok(Some(InstanceSnapshot { Ok(Some(InstanceSnapshot {
snapshot_id: None, snapshot_id: None,
metadata: Default::default(), // TODO metadata: InstanceMetadata {
ignore_unknown_instances,
..Default::default() // TODO: Fill out remaining metadata
},
name, name,
class_name, class_name,
properties, properties,

View File

@@ -12,8 +12,8 @@ use crate::{
serve_session::ServeSession, serve_session::ServeSession,
web::{ web::{
interface::{ interface::{
NotFoundError, ReadResponse, ServerInfoResponse, SubscribeResponse, PROTOCOL_VERSION, Instance, NotFoundError, ReadResponse, ServerInfoResponse, SubscribeResponse,
SERVER_VERSION, PROTOCOL_VERSION, SERVER_VERSION,
}, },
util::{json, json_ok}, util::{json, json_ok},
}, },
@@ -94,8 +94,8 @@ impl ApiService {
let argument = &request.uri().path()["/api/read/".len()..]; let argument = &request.uri().path()["/api/read/".len()..];
let requested_ids: Option<Vec<RbxId>> = argument.split(',').map(RbxId::parse_str).collect(); let requested_ids: Option<Vec<RbxId>> = argument.split(',').map(RbxId::parse_str).collect();
let _requested_ids = match requested_ids { let requested_ids = match requested_ids {
Some(id) => id, Some(ids) => ids,
None => { None => {
return Box::new(future::ok( return Box::new(future::ok(
Response::builder() Response::builder()
@@ -110,7 +110,20 @@ impl ApiService {
let message_queue = self.serve_session.message_queue(); let message_queue = self.serve_session.message_queue();
let message_cursor = message_queue.cursor(); 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 { json_ok(ReadResponse {
session_id: self.serve_session.session_id(), session_id: self.serve_session.session_id(),

View File

@@ -1,8 +1,11 @@
//! Defines all the structs needed to interact with the Rojo Serve API. //! 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 serde::{Deserialize, Serialize};
use crate::session_id::SessionId; use crate::session_id::SessionId;
@@ -17,9 +20,42 @@ pub const PROTOCOL_VERSION: u64 = 3;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct SubscribeMessage; pub struct SubscribeMessage;
// TODO
#[derive(Debug, Serialize, Deserialize)] #[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<String, RbxValue>>,
pub children: Cow<'a, [RbxId]>,
pub metadata: Option<InstanceMetadata>,
}
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 /// Response body from /api/rojo
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
@@ -35,10 +71,10 @@ pub struct ServerInfoResponse {
/// Response body from /api/read/{id} /// Response body from /api/read/{id}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ReadResponse { pub struct ReadResponse<'a> {
pub session_id: SessionId, pub session_id: SessionId,
pub message_cursor: u32, pub message_cursor: u32,
pub instances: HashMap<RbxId, Instance>, pub instances: HashMap<RbxId, Instance<'a>>,
} }
/// Response body from /api/subscribe/{cursor} /// Response body from /api/subscribe/{cursor}