Upgrade dependencies and refactor serialization in build.rs

- Updated `bincode` to version 2.0.1, modifying serialization calls to use the new API with `serde` support.
- Added new dependencies in `Cargo.lock`, including `alloca`, `atomic-waker`, and `aws-lc-rs`, ensuring compatibility with the latest features.
- Refactored file creation and serialization logic in `build.rs` for improved clarity and performance.
- Updated various dependencies in `Cargo.toml` to their latest versions, enhancing overall project stability and functionality.
This commit is contained in:
Joe 2026-02-06 18:57:29 -06:00
parent 0a4496a6c9
commit 71ea25fe0e
47 changed files with 933 additions and 517 deletions

View file

@ -0,0 +1,162 @@
---
name: Cargo Dependency Upgrades
overview: Upgrade all 11 incompatible cargo dependencies across the rojo workspace and the rbx-dom submodule, organized into tiers by risk and complexity.
todos:
- id: tier1-rand
content: Upgrade rand 0.8 -> 0.9 in rbx_types (thread_rng -> rng rename)
status: completed
- id: tier1-bitflags
content: Upgrade bitflags 1.x -> 2.x in rbx_types (faces.rs, axes.rs macro syntax)
status: completed
- id: tier2-winreg
content: Upgrade winreg 0.10 -> 0.55 in rojo (auth_cookie.rs, winapi -> windows-sys)
status: completed
- id: tier2-serde-yaml
content: Upgrade serde_yaml 0.8 -> 0.9 in rojo, rojo-insta-ext, rbx_util, rbx_reflector. Run cargo insta review for snapshot diffs.
status: completed
- id: tier3-criterion
content: Upgrade criterion 0.3/0.5 -> 0.8 in rojo and rbx_binary benchmarks
status: completed
- id: tier3-xml-rs
content: Upgrade xml-rs 0.8 -> 1.0 in rbx_xml (deserializer_core.rs, serializer_core.rs)
status: completed
- id: tier3-reqwest
content: Upgrade reqwest 0.11 -> 0.13 in rojo and rbx_reflector (blocking feature still supported)
status: completed
- id: tier4-bincode
content: Upgrade bincode 1.x -> 3.0 in rojo and rbx_types (build.rs embedding, runtime deserialize, config::legacy for compat)
status: completed
- id: tier4-hyper
content: Upgrade hyper 0.14 -> 1.x + hyper-tungstenite 0.11 -> 0.19. Add hyper-util, http-body-util. Rewrite server setup and body handling.
status: completed
- id: final-verify
content: Run cargo test, cargo clippy, cargo fmt --check across entire workspace to verify
status: completed
isProject: false
---
# Cargo Incompatible Dependency Upgrade Plan
## Inventory
11 packages across 8 `Cargo.toml` files need incompatible (semver-breaking) upgrades:
| Package | From | To | Location(s) | Risk |
| ----------------- | ------- | ------ | --------------------------------------------- | ----------- |
| rand | 0.8.5 | 0.9.2 | rbx_types | Low |
| bitflags | 1.3.2 | 2.10.0 | rbx_types | Low |
| winreg | 0.10.1 | 0.55.0 | rojo (Windows) | Low |
| serde_yaml | 0.8.26 | 0.9.34 | rojo, rojo-insta-ext, rbx_util, rbx_reflector | Low |
| criterion | 0.3/0.5 | 0.8.2 | rojo, rbx_binary | Medium |
| xml-rs | 0.8.28 | 1.0.0 | rbx_xml | Medium |
| reqwest | 0.11.27 | 0.13.2 | rojo, rbx_reflector | Medium |
| bincode | 1.3.3 | 3.0.0 | rojo, rbx_types | Medium-High |
| hyper | 0.14.32 | 1.8.1 | rojo | High |
| hyper-tungstenite | 0.11.1 | 0.19.0 | rojo | High |
**Note:** 6 of these packages live in the `rbx-dom/` submodule (separate git repo). Those changes must be committed to the submodule first, then the submodule pointer updated in rojo.
---
## Tier 1 -- Low Risk (rbx-dom submodule)
### 1a. rand 0.8 to 0.9
- **File:** [rbx-dom/rbx_types/Cargo.toml](rbx-dom/rbx_types/Cargo.toml)
- **Code change:** [rbx-dom/rbx_types/src/unique_id.rs](rbx-dom/rbx_types/src/unique_id.rs) -- 1 file, ~2 lines
- `thread_rng()` renamed to `rng()` in rand 0.9. `gen_range(0..i64::MAX)` syntax remains valid.
### 1b. bitflags 1.x to 2.x
- **File:** [rbx-dom/rbx_types/Cargo.toml](rbx-dom/rbx_types/Cargo.toml)
- **Code changes:** [rbx-dom/rbx_types/src/faces.rs](rbx-dom/rbx_types/src/faces.rs) and [rbx-dom/rbx_types/src/axes.rs](rbx-dom/rbx_types/src/axes.rs) -- 2 files
- bitflags 2.x keeps the `bitflags!` macro but struct visibility syntax changes slightly. Manual serde impls and `.bits()` / `.from_bits()` remain but some trait impls (like `Hash`) are now auto-derived.
---
## Tier 2 -- Low Risk (rojo main + crates)
### 2a. winreg 0.10 to 0.55
- **File:** [Cargo.toml](Cargo.toml) (Windows target dep)
- **Code change:** [src/auth_cookie.rs](src/auth_cookie.rs) -- 1 file, ~6 lines
- Core API (`RegKey::predef`, `open_subkey`, `get_value`) is preserved. Main change is the backend switched from `winapi` to `windows-sys`.
### 2b. serde_yaml 0.8 to 0.9
- **Files:**
- [Cargo.toml](Cargo.toml) (dev-deps)
- [crates/rojo-insta-ext/Cargo.toml](crates/rojo-insta-ext/Cargo.toml)
- [rbx-dom/rbx_util/Cargo.toml](rbx-dom/rbx_util/Cargo.toml)
- [rbx-dom/rbx_reflector/Cargo.toml](rbx-dom/rbx_reflector/Cargo.toml)
- **Code changes:** [crates/rojo-insta-ext/src/redaction_map.rs](crates/rojo-insta-ext/src/redaction_map.rs), [rbx-dom/rbx_util/src/view_binary.rs](rbx-dom/rbx_util/src/view_binary.rs), [rbx-dom/rbx_reflector/src/patches.rs](rbx-dom/rbx_reflector/src/patches.rs) -- 3 files
- serde_yaml 0.9 renames `Value::Mapping` internals and changes error types. The basic `from_str`, `to_writer`, `to_value` APIs are largely the same. May also affect insta snapshot test output formatting.
---
## Tier 3 -- Medium Risk
### 3a. criterion 0.3/0.5 to 0.8
- **Files:**
- [Cargo.toml](Cargo.toml) (dev-deps: `0.3.6`)
- [rbx-dom/rbx_binary/Cargo.toml](rbx-dom/rbx_binary/Cargo.toml) (dev-deps: `0.5.1`)
- **Code changes:** [benches/build.rs](benches/build.rs), [rbx-dom/rbx_binary/benches/suite/main.rs](rbx-dom/rbx_binary/benches/suite/main.rs), [rbx-dom/rbx_binary/benches/suite/util.rs](rbx-dom/rbx_binary/benches/suite/util.rs) -- 3 files
- criterion 0.8 removed `criterion_group!` / `criterion_main!` macros in favor of a new runner. Benchmark functions remain similar but setup code will change.
### 3b. xml-rs 0.8 to 1.0
- **File:** [rbx-dom/rbx_xml/Cargo.toml](rbx-dom/rbx_xml/Cargo.toml)
- **Code changes:** [rbx-dom/rbx_xml/src/deserializer_core.rs](rbx-dom/rbx_xml/src/deserializer_core.rs), [rbx-dom/rbx_xml/src/serializer_core.rs](rbx-dom/rbx_xml/src/serializer_core.rs), and [rbx-dom/rbx_xml/src/types/physical_properties.rs](rbx-dom/rbx_xml/src/types/physical_properties.rs) -- 3 files, ~300 lines
- xml-rs 1.0 rebrands to the `xml` crate. The event-based reader/writer API has the same structure but types/namespaces changed. `ParserConfig`, `EventReader`, `EmitterConfig`, `EventWriter` all have equivalents but may be renamed or restructured.
### 3c. reqwest 0.11 to 0.13
- **Files:** [Cargo.toml](Cargo.toml), [rbx-dom/rbx_reflector/Cargo.toml](rbx-dom/rbx_reflector/Cargo.toml)
- **Code changes:** [src/cli/studio.rs](src/cli/studio.rs), [src/cli/syncback.rs](src/cli/syncback.rs), [src/cli/upload.rs](src/cli/upload.rs) -- 3 files
- reqwest 0.13 **still supports `blocking**`. Main breaking changes: internal HTTP client changes, some header/feature reorganization. The `reqwest::blocking::Client` API is preserved.
---
## Tier 4 -- High Risk
### 4a. bincode 1.x to 3.0
- **Files:** [Cargo.toml](Cargo.toml) (deps + build-deps), [rbx-dom/rbx_types/Cargo.toml](rbx-dom/rbx_types/Cargo.toml) (dev-deps)
- **Code changes:**
- [build.rs](build.rs) -- `bincode::serialize_into` calls
- [src/cli/plugin.rs](src/cli/plugin.rs) -- `bincode::deserialize` call
- [src/cli/init.rs](src/cli/init.rs) -- `bincode::deserialize` call
- ~16 test usages across `rbx-dom/rbx_types/src/` (serialization roundtrips)
- bincode 3.0 completely rewrites the API. Serde support is opt-in via the `serde` feature. `serialize`/`deserialize` become `bincode::serde::encode_to_vec` / `bincode::serde::decode_from_slice` with an explicit `Configuration`. For backward compatibility with existing bincode 1.x-encoded data (embedded plugin/template snapshots), use `config::legacy()`.
- **Critical concern:** The build.rs embeds snapshots at compile time that are deserialized at runtime. The format must remain compatible across the upgrade, or the embedded blobs must be regenerated.
### 4b. hyper 0.14 to 1.x + hyper-tungstenite 0.11 to 0.19
- **Files:** [Cargo.toml](Cargo.toml)
- **New dependency needed:** `hyper-util` (provides the server and service utilities removed from hyper core)
- **Code changes:**
- [src/web/mod.rs](src/web/mod.rs) -- Server setup (~25 lines). `hyper::Server::bind` replaced by `hyper_util::server::conn::auto::Builder` + a TCP accept loop.
- [src/web/api.rs](src/web/api.rs) -- Request/response handling (~50 lines). `hyper::Body` becomes a trait; use `http_body_util::Full<Bytes>` or `BoxBody`.
- [src/web/ui.rs](src/web/ui.rs) -- Same Body/Response changes (~20 lines).
- [src/web/util.rs](src/web/util.rs) -- Response builder helpers (~30 lines). `Body::from()` becomes `Full::new(Bytes::from(...))`.
- [tests/rojo_test/serve_util.rs](tests/rojo_test/serve_util.rs) -- Test WebSocket client (~15 lines).
- **New dependencies:** `hyper-util`, `http-body-util`, `bytes` (if not already present)
- This is the most architecturally impactful change. The server accept loop, body type system, and service pattern all change fundamentally.
---
## Execution Strategy
Work in this order so each tier builds on stable ground:
1. **Tier 1** (rbx-dom: rand, bitflags) -- Isolated to rbx_types, no downstream API changes
2. **Tier 2** (winreg, serde_yaml) -- Simple API surface, low blast radius
3. **Tier 3** (criterion, xml-rs, reqwest) -- More code changes but well-scoped
4. **Tier 4** (bincode, hyper stack) -- Architectural changes, do last
After each tier: run `cargo test` and `cargo clippy` to verify. For rbx-dom changes, commit to the submodule first, then update the submodule pointer in the main repo.
**serde_yaml snapshot tests:** The 0.8 to 0.9 upgrade may change YAML serialization output slightly (e.g., tag formatting). Run `cargo insta review` after upgrading to accept snapshot diffs.

843
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -57,7 +57,7 @@ rbx_xml = { path = "rbx-dom/rbx_xml" }
anyhow = "1.0.101" anyhow = "1.0.101"
backtrace = "0.3.76" backtrace = "0.3.76"
bincode = "1.3.3" bincode = { version = "2", features = ["serde"] }
crossbeam-channel = "0.5.15" crossbeam-channel = "0.5.15"
csv = "1.4.0" csv = "1.4.0"
env_logger = "0.11" env_logger = "0.11"
@ -65,18 +65,21 @@ fs-err = "3"
futures = "0.3.31" futures = "0.3.31"
globset = "0.4.18" globset = "0.4.18"
humantime = "2.3.0" humantime = "2.3.0"
hyper = { version = "0.14.32", features = ["server", "tcp", "http1"] } hyper = { version = "1", features = ["server", "http1"] }
hyper-tungstenite = "0.11.1" hyper-util = { version = "0.1", features = ["tokio"] }
http-body-util = "0.1"
bytes = "1"
hyper-tungstenite = "0.19"
jod-thread = "1.0.0" jod-thread = "1.0.0"
log = "0.4.29" log = "0.4.29"
num_cpus = "1.17.0" num_cpus = "1.17.0"
opener = "0.8.4" opener = "0.8.4"
rayon = "1.11.0" rayon = "1.11.0"
rbx_cookie = "0.1.5" rbx_cookie = "0.1.5"
reqwest = { version = "0.11.27", default-features = false, features = [ reqwest = { version = "0.13", default-features = false, features = [
"blocking", "blocking",
"json", "json",
"rustls-tls", "rustls",
"gzip", "gzip",
"brotli", "brotli",
"deflate", "deflate",
@ -105,14 +108,14 @@ rmp-serde = "1.3.1"
serde_bytes = "0.11.19" serde_bytes = "0.11.19"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winreg = "0.10.1" winreg = "0.55"
[build-dependencies] [build-dependencies]
memofs = { version = "0.3.0", path = "crates/memofs" } memofs = { version = "0.3.0", path = "crates/memofs" }
embed-resource = "3.0.6" embed-resource = "3.0.6"
anyhow = "1.0.101" anyhow = "1.0.101"
bincode = "1.3.3" bincode = { version = "2", features = ["serde"] }
fs-err = "3" fs-err = "3"
maplit = "1.0.2" maplit = "1.0.2"
semver = "1.0.27" semver = "1.0.27"
@ -120,10 +123,10 @@ semver = "1.0.27"
[dev-dependencies] [dev-dependencies]
rojo-insta-ext = { path = "crates/rojo-insta-ext" } rojo-insta-ext = { path = "crates/rojo-insta-ext" }
criterion = "0.3.6" criterion = "0.8"
insta = { version = "1.46.3", features = ["redactions", "yaml"] } insta = { version = "1.46.3", features = ["redactions", "yaml"] }
paste = "1.0.15" paste = "1.0.15"
pretty_assertions = "1.4.1" pretty_assertions = "1.4.1"
regex = "1" regex = "1"
serde_yaml = "0.8.26" serde_yaml = "0.9"
walkdir = "2.5.0" walkdir = "2.5.0"

View file

@ -99,11 +99,19 @@ fn main() -> Result<(), anyhow::Error> {
}), }),
}); });
let template_file = File::create(Path::new(&out_dir).join("templates.bincode"))?; let mut template_file = File::create(Path::new(&out_dir).join("templates.bincode"))?;
let plugin_file = File::create(Path::new(&out_dir).join("plugin.bincode"))?; let mut plugin_file = File::create(Path::new(&out_dir).join("plugin.bincode"))?;
bincode::serialize_into(plugin_file, &plugin_snapshot)?; bincode::serde::encode_into_std_write(
bincode::serialize_into(template_file, &template_snapshot)?; &plugin_snapshot,
&mut plugin_file,
bincode::config::standard(),
)?;
bincode::serde::encode_into_std_write(
&template_snapshot,
&mut template_file,
bincode::config::standard(),
)?;
println!("cargo:rerun-if-changed=build/windows/rojo-manifest.rc"); println!("cargo:rerun-if-changed=build/windows/rojo-manifest.rc");
println!("cargo:rerun-if-changed=build/windows/rojo.manifest"); println!("cargo:rerun-if-changed=build/windows/rojo.manifest");

View file

@ -7,4 +7,4 @@ publish = false
[dependencies] [dependencies]
serde = "1.0.228" serde = "1.0.228"
serde_yaml = "0.8.26" serde_yaml = "0.9"

@ -1 +1 @@
Subproject commit a5bc66e39f1d51469d8190cd4233850ea96f519b Subproject commit 258802d5619fefec7a8558465c0c872e8b7968ed

View file

@ -1,7 +1,6 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
id-2: id-2:
@ -14,7 +13,6 @@ instances:
Parent: "00000000000000000000000000000000" Parent: "00000000000000000000000000000000"
Properties: Properties:
Source: Source:
String: "-- Edited contents" "!String": "-- Edited contents"
messageCursor: 1 messageCursor: 1
sessionId: id-1 sessionId: id-1

View file

@ -13,6 +13,6 @@ instances:
Parent: "00000000000000000000000000000000" Parent: "00000000000000000000000000000000"
Properties: Properties:
Source: Source:
String: "-- Original contents" "!String": "-- Original contents"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -13,7 +13,7 @@ body:
changedName: ~ changedName: ~
changedProperties: changedProperties:
Source: Source:
String: "-- Edited contents" "!String": "-- Edited contents"
id: id-2 id: id-2
packetType: messages packetType: messages
sessionId: id-1 sessionId: id-1

View file

@ -23,6 +23,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
messageCursor: 1 messageCursor: 1
sessionId: id-1 sessionId: id-1

View file

@ -16,7 +16,7 @@ body:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
removed: [] removed: []
updated: [] updated: []
packetType: messages packetType: messages

View file

@ -25,7 +25,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-4: id-4:
Children: [] Children: []
ClassName: ObjectValue ClassName: ObjectValue
@ -36,9 +36,9 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 9893f640faccb9150197026b0ca91712
id-5: id-5:
Children: [] Children: []
ClassName: MeshPart ClassName: MeshPart
@ -49,8 +49,8 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
MeshId: MeshId:
ContentId: "rbxasset://fonts/sword.mesh" "!ContentId": "rbxasset://fonts/sword.mesh"
TextureID: TextureID:
ContentId: "rbxasset://textures/SwordTexture.png" "!ContentId": "rbxasset://textures/SwordTexture.png"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -26,7 +26,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-4: id-4:
Children: [] Children: []
ClassName: Model ClassName: Model
@ -37,7 +37,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-5: id-5:
Children: [] Children: []
ClassName: Tool ClassName: Tool
@ -48,7 +48,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-6: id-6:
Children: [] Children: []
ClassName: Actor ClassName: Actor
@ -59,6 +59,6 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
messageCursor: 1 messageCursor: 1
sessionId: id-1 sessionId: id-1

View file

@ -16,7 +16,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
removed: [] removed: []
updated: updated:
- changedClassName: ~ - changedClassName: ~

View file

@ -1,7 +1,6 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
id-10: id-10:
@ -14,7 +13,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #6" "!String": "File #6"
id-11: id-11:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -25,7 +24,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #7" "!String": "File #7"
id-12: id-12:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -36,7 +35,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #8" "!String": "File #8"
id-13: id-13:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -47,7 +46,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #9" "!String": "File #9"
id-2: id-2:
Children: Children:
- id-3 - id-3
@ -87,7 +86,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #0" "!String": "File #0"
id-5: id-5:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -98,7 +97,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #1" "!String": "File #1"
id-6: id-6:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -109,7 +108,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #2" "!String": "File #2"
id-7: id-7:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -120,7 +119,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #3" "!String": "File #3"
id-8: id-8:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -131,7 +130,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #4" "!String": "File #4"
id-9: id-9:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -142,7 +141,6 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #5" "!String": "File #5"
messageCursor: 1 messageCursor: 1
sessionId: id-1 sessionId: id-1

View file

@ -16,7 +16,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #6" "!String": "File #6"
id-11: id-11:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -27,7 +27,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #7" "!String": "File #7"
id-12: id-12:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -38,7 +38,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #8" "!String": "File #8"
id-13: id-13:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -49,7 +49,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #9" "!String": "File #9"
id-3: id-3:
Children: Children:
- id-4 - id-4
@ -79,7 +79,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #0" "!String": "File #0"
id-5: id-5:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -90,7 +90,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #1" "!String": "File #1"
id-6: id-6:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -101,7 +101,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #2" "!String": "File #2"
id-7: id-7:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -112,7 +112,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #3" "!String": "File #3"
id-8: id-8:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -123,7 +123,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #4" "!String": "File #4"
id-9: id-9:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -134,7 +134,7 @@ body:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "File #5" "!String": "File #5"
removed: [] removed: []
updated: [] updated: []
packetType: messages packetType: messages

View file

@ -33,7 +33,6 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
Int64: 1337 "!Int64": 1337
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -1,6 +1,5 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
assertion_line: 338
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
@ -34,7 +33,6 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
Bool: true "!Bool": true
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -1,6 +1,5 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
assertion_line: 370
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
@ -14,6 +13,6 @@ instances:
Parent: "00000000000000000000000000000000" Parent: "00000000000000000000000000000000"
Properties: Properties:
Value: Value:
String: "If this isn't named `no_name_top_level_project`, something went wrong!" "!String": "If this isn't named `no_name_top_level_project`, something went wrong!"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -1,6 +1,5 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
assertion_line: 357
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
@ -14,7 +13,6 @@ instances:
Parent: "00000000000000000000000000000000" Parent: "00000000000000000000000000000000"
Properties: Properties:
Value: Value:
String: "If this isn't named `no_name_top_level_project`, something went wrong!" "!String": "If this isn't named `no_name_top_level_project`, something went wrong!"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -25,7 +25,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-4: id-4:
Children: [] Children: []
ClassName: Model ClassName: Model
@ -36,7 +36,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-5: id-5:
Children: [] Children: []
ClassName: Tool ClassName: Tool
@ -47,6 +47,6 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -13,9 +13,9 @@ instances:
Parent: id-9 Parent: id-9
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-9 "!Ref": a014b12bf90014847f564374c73a5f38
id-11: id-11:
Children: [] Children: []
ClassName: Model ClassName: Model
@ -26,11 +26,11 @@ instances:
Parent: id-7 Parent: id-7
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
PrimaryPart: PrimaryPart:
Ref: id-9 "!Ref": a014b12bf90014847f564374c73a5f38
id-2: id-2:
Children: Children:
- id-3 - id-3
@ -55,7 +55,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-4: id-4:
Children: [] Children: []
ClassName: ObjectValue ClassName: ObjectValue
@ -66,9 +66,9 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 4d3455270f6618409e7d40dbcad9e25b
id-5: id-5:
Children: Children:
- id-6 - id-6
@ -89,9 +89,9 @@ instances:
Parent: id-5 Parent: id-5
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 4d3455270f6618409e7d40dbcad9e25b
id-7: id-7:
Children: Children:
- id-8 - id-8
@ -104,7 +104,7 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
id-8: id-8:
Children: [] Children: []
ClassName: Model ClassName: Model
@ -115,11 +115,11 @@ instances:
Parent: id-7 Parent: id-7
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
PrimaryPart: PrimaryPart:
Ref: id-7 "!Ref": 4536e7ddde75409951458987be6ccfb5
id-9: id-9:
Children: Children:
- id-10 - id-10

View file

@ -13,9 +13,9 @@ instances:
Parent: id-9 Parent: id-9
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-9 "!Ref": a014b12bf90014847f564374c73a5f38
id-2: id-2:
Children: Children:
- id-3 - id-3
@ -40,7 +40,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-4: id-4:
Children: [] Children: []
ClassName: ObjectValue ClassName: ObjectValue
@ -51,9 +51,9 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 4d3455270f6618409e7d40dbcad9e25b
id-5: id-5:
Children: Children:
- id-6 - id-6
@ -74,9 +74,9 @@ instances:
Parent: id-5 Parent: id-5
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 4d3455270f6618409e7d40dbcad9e25b
id-7: id-7:
Children: Children:
- id-8 - id-8
@ -97,11 +97,11 @@ instances:
Parent: id-7 Parent: id-7
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
PrimaryPart: PrimaryPart:
Ref: id-7 "!Ref": 4536e7ddde75409951458987be6ccfb5
id-9: id-9:
Children: Children:
- id-10 - id-10

View file

@ -13,9 +13,9 @@ instances:
Parent: id-9 Parent: id-9
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-9 "!Ref": a2c2197b7d6e19e64b8991926744f3a6
id-2: id-2:
Children: Children:
- id-3 - id-3
@ -40,7 +40,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-4: id-4:
Children: [] Children: []
ClassName: ObjectValue ClassName: ObjectValue
@ -51,9 +51,9 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 75d2ce9353a6c62f29130f18c35c89ce
id-5: id-5:
Children: Children:
- id-6 - id-6
@ -74,9 +74,9 @@ instances:
Parent: id-5 Parent: id-5
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 75d2ce9353a6c62f29130f18c35c89ce
id-7: id-7:
Children: Children:
- id-8 - id-8
@ -97,13 +97,13 @@ instances:
Parent: id-7 Parent: id-7
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
PrimaryPart: PrimaryPart:
Ref: id-7 "!Ref": 103b2053eb8c4ea0a65500d5c20bd84f
Scale: Scale:
Float32: 1 "!Float32": 1
id-9: id-9:
Children: Children:
- id-10 - id-10

View file

@ -13,9 +13,9 @@ instances:
Parent: id-9 Parent: id-9
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-9 "!Ref": a2c2197b7d6e19e64b8991926744f3a6
id-2: id-2:
Children: Children:
- id-3 - id-3
@ -40,7 +40,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
id-4: id-4:
Children: [] Children: []
ClassName: ObjectValue ClassName: ObjectValue
@ -51,9 +51,9 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 75d2ce9353a6c62f29130f18c35c89ce
id-5: id-5:
Children: Children:
- id-6 - id-6
@ -74,9 +74,9 @@ instances:
Parent: id-5 Parent: id-5
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-5 "!Ref": 75d2ce9353a6c62f29130f18c35c89ce
id-7: id-7:
Children: Children:
- id-8 - id-8
@ -97,11 +97,11 @@ instances:
Parent: id-7 Parent: id-7
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
PrimaryPart: PrimaryPart:
Ref: id-7 "!Ref": 103b2053eb8c4ea0a65500d5c20bd84f
id-9: id-9:
Children: Children:
- id-10 - id-10

View file

@ -13,11 +13,11 @@ body:
changedName: ~ changedName: ~
changedProperties: changedProperties:
Attributes: Attributes:
Attributes: "!Attributes":
Rojo_Target_PrimaryPart: Rojo_Target_PrimaryPart:
String: model target "!String": model target
Scale: Scale:
Float32: 1 "!Float32": 1
id: id-8 id: id-8
packetType: messages packetType: messages
sessionId: id-1 sessionId: id-1

View file

@ -23,8 +23,8 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-4 "!Ref": ca113df936e8659c00936176b40b02ae
messageCursor: 1 messageCursor: 1
sessionId: id-1 sessionId: id-1

View file

@ -24,9 +24,9 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
Value: Value:
Ref: id-4 "!Ref": ca113df936e8659c00936176b40b02ae
id-4: id-4:
Children: [] Children: []
ClassName: ObjectValue ClassName: ObjectValue
@ -37,6 +37,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -16,11 +16,11 @@ body:
Parent: id-7 Parent: id-7
Properties: Properties:
Attributes: Attributes:
Attributes: {} "!Attributes": {}
NeedsPivotMigration: NeedsPivotMigration:
Bool: false "!Bool": false
PrimaryPart: PrimaryPart:
Ref: id-9 "!Ref": a014b12bf90014847f564374c73a5f38
removed: [] removed: []
updated: updated:
- changedClassName: ~ - changedClassName: ~
@ -29,18 +29,18 @@ body:
changedName: ~ changedName: ~
changedProperties: changedProperties:
Attributes: Attributes:
Attributes: "!Attributes":
Rojo_Id: Rojo_Id:
String: model target 2 "!String": model target 2
id: id-7 id: id-7
- changedClassName: ~ - changedClassName: ~
changedMetadata: ~ changedMetadata: ~
changedName: ~ changedName: ~
changedProperties: changedProperties:
Attributes: Attributes:
Attributes: "!Attributes":
Rojo_Target_PrimaryPart: Rojo_Target_PrimaryPart:
String: model target 2 "!String": model target 2
PrimaryPart: ~ PrimaryPart: ~
id: id-8 id: id-8
packetType: messages packetType: messages

View file

@ -1,7 +1,6 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
id-2: id-2:
@ -24,7 +23,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Value: Value:
String: This file will be removed! "!String": This file will be removed!
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -24,9 +24,9 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
RunContext: RunContext:
Enum: 1 "!Enum": 1
Source: Source:
String: "-- Hello, from bar!" "!String": "-- Hello, from bar!"
id-4: id-4:
Children: [] Children: []
ClassName: ModuleScript ClassName: ModuleScript
@ -37,6 +37,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Source: Source:
String: Updated foo! "!String": Updated foo!
messageCursor: 1 messageCursor: 1
sessionId: id-1 sessionId: id-1

View file

@ -24,9 +24,9 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
RunContext: RunContext:
Enum: 1 "!Enum": 1
Source: Source:
String: "-- Hello, from bar!" "!String": "-- Hello, from bar!"
id-4: id-4:
Children: [] Children: []
ClassName: ModuleScript ClassName: ModuleScript
@ -37,6 +37,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Source: Source:
String: "-- Hello, from foo!" "!String": "-- Hello, from foo!"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -13,7 +13,7 @@ body:
changedName: ~ changedName: ~
changedProperties: changedProperties:
Source: Source:
String: Updated foo! "!String": Updated foo!
id: id-4 id: id-4
packetType: messages packetType: messages
sessionId: id-1 sessionId: id-1

View file

@ -23,6 +23,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Value: Value:
String: "Hello, world!" "!String": "Hello, world!"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -27,9 +27,9 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
RunContext: RunContext:
Enum: 1 "!Enum": 1
Source: Source:
String: "-- Hello, from bar (a Script)!" "!String": "-- Hello, from bar (a Script)!"
id-4: id-4:
Children: [] Children: []
ClassName: Script ClassName: Script
@ -40,9 +40,9 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
RunContext: RunContext:
Enum: 2 "!Enum": 2
Source: Source:
String: "-- Hello, from baz (a LocalScript)!" "!String": "-- Hello, from baz (a LocalScript)!"
id-5: id-5:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -53,7 +53,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Value: Value:
String: "Hello, from cat (a StringValue)!" "!String": "Hello, from cat (a StringValue)!"
id-6: id-6:
Children: [] Children: []
ClassName: ModuleScript ClassName: ModuleScript
@ -64,7 +64,7 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Source: Source:
String: "-- Hello, from foo (a ModuleScript)!" "!String": "-- Hello, from foo (a ModuleScript)!"
id-7: id-7:
Children: [] Children: []
ClassName: StringValue ClassName: StringValue
@ -75,6 +75,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Value: Value:
String: "Hello, from qux (a .rojo file that's turned into a StringValue)!" "!String": "Hello, from qux (a .rojo file that's turned into a StringValue)!"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -1,6 +1,5 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
assertion_line: 303
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
@ -24,7 +23,6 @@ instances:
Parent: id-2 Parent: id-2
Properties: Properties:
Source: Source:
String: "return {\"This file has no extension but should be a ModuleScript named `no_extension`\"}" "!String": "return {\"This file has no extension but should be a ModuleScript named `no_extension`\"}"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -1,6 +1,5 @@
--- ---
source: tests/tests/serve.rs source: tests/tests/serve.rs
assertion_line: 389
expression: "read_response.intern_and_redact(&mut redactions, root_id)" expression: "read_response.intern_and_redact(&mut redactions, root_id)"
--- ---
instances: instances:
@ -15,7 +14,7 @@ instances:
Parent: "00000000000000000000000000000000" Parent: "00000000000000000000000000000000"
Properties: Properties:
Value: Value:
String: "This should be named `sync_rule_no_name_project` and have a child at `src/not_a_project`" "!String": "This should be named `sync_rule_no_name_project` and have a child at `src/not_a_project`"
id-3: id-3:
Children: Children:
- id-4 - id-4
@ -36,6 +35,6 @@ instances:
Parent: id-3 Parent: id-3
Properties: Properties:
Value: Value:
String: "If this isn't named `not_a_project`, something has gone wrong!" "!String": "If this isn't named `not_a_project`, something has gone wrong!"
messageCursor: 0 messageCursor: 0
sessionId: id-1 sessionId: id-1

View file

@ -229,8 +229,9 @@ impl InitKind {
Self::Plugin => "plugin", Self::Plugin => "plugin",
}; };
let snapshot: VfsSnapshot = bincode::deserialize(TEMPLATE_BINCODE) let (snapshot, _): (VfsSnapshot, usize) =
.expect("Rojo's templates were not properly packed into Rojo's binary"); bincode::serde::decode_from_slice(TEMPLATE_BINCODE, bincode::config::standard())
.expect("Rojo's templates were not properly packed into Rojo's binary");
if let VfsSnapshot::Dir { mut children } = snapshot { if let VfsSnapshot::Dir { mut children } = snapshot {
if let Some(template) = children.remove(template_path) { if let Some(template) = children.remove(template_path) {

View file

@ -47,8 +47,9 @@ impl PluginSubcommand {
} }
fn initialize_plugin() -> anyhow::Result<ServeSession> { fn initialize_plugin() -> anyhow::Result<ServeSession> {
let plugin_snapshot: VfsSnapshot = bincode::deserialize(PLUGIN_BINCODE) let (plugin_snapshot, _): (VfsSnapshot, usize) =
.expect("Rojo's plugin was not properly packed into Rojo's binary"); bincode::serde::decode_from_slice(PLUGIN_BINCODE, bincode::config::standard())
.expect("Rojo's plugin was not properly packed into Rojo's binary");
let mut in_memory_fs = InMemoryFs::new(); let mut in_memory_fs = InMemoryFs::new();
in_memory_fs.load_snapshot("/plugin", plugin_snapshot)?; in_memory_fs.load_snapshot("/plugin", plugin_snapshot)?;

View file

@ -1,7 +1,6 @@
--- ---
source: src/snapshot/tests/apply.rs source: src/snapshot/tests/apply.rs
expression: applied_patch_value expression: applied_patch_value
--- ---
removed: [] removed: []
added: [] added: []
@ -11,6 +10,5 @@ updated:
changed_class_name: ~ changed_class_name: ~
changed_properties: changed_properties:
Foo: Foo:
String: Value of Foo "!String": Value of Foo
changed_metadata: ~ changed_metadata: ~

View file

@ -7,7 +7,7 @@ name: ROOT
class_name: ROOT class_name: ROOT
properties: properties:
Foo: Foo:
String: Value of Foo "!String": Value of Foo
metadata: metadata:
ignore_unknown_instances: false ignore_unknown_instances: false
relevant_paths: [] relevant_paths: []

View file

@ -7,7 +7,7 @@ name: ROOT
class_name: ROOT class_name: ROOT
properties: properties:
Foo: Foo:
String: Should be removed "!String": Should be removed
metadata: metadata:
ignore_unknown_instances: false ignore_unknown_instances: false
relevant_paths: [] relevant_paths: []

View file

@ -1,7 +1,6 @@
--- ---
source: src/snapshot/tests/compute.rs source: src/snapshot/tests/compute.rs
expression: patch_value expression: patch_value
--- ---
removed_instances: [] removed_instances: []
added_instances: [] added_instances: []
@ -11,6 +10,5 @@ updated_instances:
changed_class_name: ~ changed_class_name: ~
changed_properties: changed_properties:
PropertyName: PropertyName:
String: "Hello, world!" "!String": "Hello, world!"
changed_metadata: ~ changed_metadata: ~

View file

@ -9,8 +9,10 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use bytes::Bytes;
use futures::{sink::SinkExt, stream::StreamExt}; use futures::{sink::SinkExt, stream::StreamExt};
use hyper::{body, Body, Method, Request, Response, StatusCode}; use http_body_util::{BodyExt, Full};
use hyper::{body::Incoming, Method, Request, Response, StatusCode};
use hyper_tungstenite::{is_upgrade_request, tungstenite::Message, upgrade, HyperWebsocket}; use hyper_tungstenite::{is_upgrade_request, tungstenite::Message, upgrade, HyperWebsocket};
use opener::OpenError; use opener::OpenError;
use rbx_dom_weak::{ use rbx_dom_weak::{
@ -116,7 +118,10 @@ fn variant_to_json(variant: &Variant) -> Option<serde_json::Value> {
} }
} }
pub async fn call(serve_session: Arc<ServeSession>, mut request: Request<Body>) -> Response<Body> { pub async fn call(
serve_session: Arc<ServeSession>,
mut request: Request<Incoming>,
) -> Response<Full<Bytes>> {
let service = ApiService::new(serve_session); let service = ApiService::new(serve_session);
match (request.method(), request.uri().path()) { match (request.method(), request.uri().path()) {
@ -253,7 +258,7 @@ impl ApiService {
} }
/// Get a summary of information about the server /// Get a summary of information about the server
async fn handle_api_rojo(&self) -> Response<Body> { async fn handle_api_rojo(&self) -> Response<Full<Bytes>> {
let tree = self.serve_session.tree(); let tree = self.serve_session.tree();
let root_instance_id = tree.get_root_id(); let root_instance_id = tree.get_root_id();
@ -281,7 +286,7 @@ impl ApiService {
} }
/// Handle WebSocket upgrade for real-time message streaming /// Handle WebSocket upgrade for real-time message streaming
async fn handle_api_socket(&self, request: &mut Request<Body>) -> Response<Body> { async fn handle_api_socket(&self, request: &mut Request<Incoming>) -> Response<Full<Bytes>> {
let argument = &request.uri().path()["/api/socket/".len()..]; let argument = &request.uri().path()["/api/socket/".len()..];
let input_cursor: u32 = match argument.parse() { let input_cursor: u32 = match argument.parse() {
Ok(v) => v, Ok(v) => v,
@ -318,11 +323,11 @@ impl ApiService {
response response
} }
async fn handle_api_write(&self, request: Request<Body>) -> Response<Body> { async fn handle_api_write(&self, request: Request<Incoming>) -> Response<Full<Bytes>> {
let session_id = self.serve_session.session_id(); let session_id = self.serve_session.session_id();
let tree_mutation_sender = self.serve_session.tree_mutation_sender(); let tree_mutation_sender = self.serve_session.tree_mutation_sender();
let body = body::to_bytes(request.into_body()).await.unwrap(); let body = request.into_body().collect().await.unwrap().to_bytes();
let request: WriteRequest = match deserialize_msgpack(&body) { let request: WriteRequest = match deserialize_msgpack(&body) {
Ok(request) => request, Ok(request) => request,
@ -2411,7 +2416,7 @@ impl ApiService {
} }
} }
async fn handle_api_read(&self, request: Request<Body>) -> Response<Body> { async fn handle_api_read(&self, request: Request<Incoming>) -> Response<Full<Bytes>> {
let argument = &request.uri().path()["/api/read/".len()..]; let argument = &request.uri().path()["/api/read/".len()..];
let requested_ids: Result<Vec<Ref>, _> = argument.split(',').map(Ref::from_str).collect(); let requested_ids: Result<Vec<Ref>, _> = argument.split(',').map(Ref::from_str).collect();
@ -2496,7 +2501,7 @@ impl ApiService {
/// The returned model is a folder that contains ObjectValues with names /// The returned model is a folder that contains ObjectValues with names
/// that correspond to the requested Instances. These values have their /// that correspond to the requested Instances. These values have their
/// `Value` property set to point to the requested Instance. /// `Value` property set to point to the requested Instance.
async fn handle_api_serialize(&self, request: Request<Body>) -> Response<Body> { async fn handle_api_serialize(&self, request: Request<Incoming>) -> Response<Full<Bytes>> {
let argument = &request.uri().path()["/api/serialize/".len()..]; let argument = &request.uri().path()["/api/serialize/".len()..];
let requested_ids: Result<Vec<Ref>, _> = argument.split(',').map(Ref::from_str).collect(); let requested_ids: Result<Vec<Ref>, _> = argument.split(',').map(Ref::from_str).collect();
@ -2558,7 +2563,7 @@ impl ApiService {
/// provided IDs. Used because the plugin does not store a RojoTree, /// provided IDs. Used because the plugin does not store a RojoTree,
/// and referent properties need to be updated after the serialize /// and referent properties need to be updated after the serialize
/// endpoint is used. /// endpoint is used.
async fn handle_api_ref_patch(&self, request: Request<Body>) -> Response<Body> { async fn handle_api_ref_patch(&self, request: Request<Incoming>) -> Response<Full<Bytes>> {
let argument = &request.uri().path()["/api/ref-patch/".len()..]; let argument = &request.uri().path()["/api/ref-patch/".len()..];
let requested_ids: Result<Vec<Ref>, _> = argument.split(',').map(Ref::from_str).collect(); let requested_ids: Result<Vec<Ref>, _> = argument.split(',').map(Ref::from_str).collect();
@ -2613,7 +2618,7 @@ impl ApiService {
} }
/// Open a script with the given ID in the user's default text editor. /// Open a script with the given ID in the user's default text editor.
async fn handle_api_open(&self, request: Request<Body>) -> Response<Body> { async fn handle_api_open(&self, request: Request<Incoming>) -> Response<Full<Bytes>> {
let argument = &request.uri().path()["/api/open/".len()..]; let argument = &request.uri().path()["/api/open/".len()..];
let requested_id = match Ref::from_str(argument) { let requested_id = match Ref::from_str(argument) {
Ok(id) => id, Ok(id) => id,
@ -2786,7 +2791,7 @@ async fn handle_websocket_subscription(
log::debug!("Sending batch of messages over WebSocket subscription"); log::debug!("Sending batch of messages over WebSocket subscription");
if websocket.send(Message::Binary(msgpack_message)).await.is_err() { if websocket.send(Message::Binary(msgpack_message.into())).await.is_err() {
// Client disconnected // Client disconnected
log::debug!("WebSocket subscription closed by client"); log::debug!("WebSocket subscription closed by client");
break; break;

View file

@ -12,11 +12,12 @@ use std::convert::Infallible;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc; use std::sync::Arc;
use hyper::{ use hyper::body::Incoming;
server::Server, use hyper::server::conn::http1;
service::{make_service_fn, service_fn}, use hyper::service::service_fn;
Body, Request, use hyper::Request;
}; use hyper_util::rt::TokioIo;
use tokio::net::TcpListener;
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use crate::serve_session::ServeSession; use crate::serve_session::ServeSession;
@ -33,29 +34,37 @@ impl LiveServer {
pub fn start(self, address: SocketAddr) { pub fn start(self, address: SocketAddr) {
let serve_session = Arc::clone(&self.serve_session); let serve_session = Arc::clone(&self.serve_session);
let make_service = make_service_fn(move |_conn| { let rt = Runtime::new().unwrap();
let serve_session = Arc::clone(&serve_session); rt.block_on(async move {
let listener = TcpListener::bind(address).await.unwrap();
async { loop {
let service = move |req: Request<Body>| { let (stream, _) = listener.accept().await.unwrap();
let serve_session = Arc::clone(&serve_session); let io = TokioIo::new(stream);
let serve_session = Arc::clone(&serve_session);
async move { tokio::spawn(async move {
if req.uri().path().starts_with("/api") { let service = service_fn(move |req: Request<Incoming>| {
Ok::<_, Infallible>(api::call(serve_session, req).await) let serve_session = Arc::clone(&serve_session);
} else {
Ok::<_, Infallible>(ui::call(serve_session, req).await) async move {
if req.uri().path().starts_with("/api") {
Ok::<_, Infallible>(api::call(serve_session, req).await)
} else {
Ok::<_, Infallible>(ui::call(serve_session, req).await)
}
} }
} });
};
Ok::<_, Infallible>(service_fn(service)) if let Err(err) = http1::Builder::new()
.serve_connection(io, service)
.with_upgrades()
.await
{
log::error!("Error serving connection: {err}");
}
});
} }
}); });
let rt = Runtime::new().unwrap();
let _guard = rt.enter();
let server = Server::bind(&address).serve(make_service);
rt.block_on(server).unwrap();
} }
} }

View file

@ -6,7 +6,9 @@
use std::{borrow::Cow, sync::Arc, time::Duration}; use std::{borrow::Cow, sync::Arc, time::Duration};
use hyper::{header, Body, Method, Request, Response, StatusCode}; use bytes::Bytes;
use http_body_util::Full;
use hyper::{body::Incoming, header, Method, Request, Response, StatusCode};
use rbx_dom_weak::types::{Ref, Variant}; use rbx_dom_weak::types::{Ref, Variant};
use ritz::{html, Fragment, HtmlContent, HtmlSelfClosingTag}; use ritz::{html, Fragment, HtmlContent, HtmlSelfClosingTag};
@ -20,7 +22,10 @@ use crate::{
}, },
}; };
pub async fn call(serve_session: Arc<ServeSession>, request: Request<Body>) -> Response<Body> { pub async fn call(
serve_session: Arc<ServeSession>,
request: Request<Incoming>,
) -> Response<Full<Bytes>> {
let service = UiService::new(serve_session); let service = UiService::new(serve_session);
match (request.method(), request.uri().path()) { match (request.method(), request.uri().path()) {
@ -44,21 +49,21 @@ impl UiService {
UiService { serve_session } UiService { serve_session }
} }
fn handle_logo(&self) -> Response<Body> { fn handle_logo(&self) -> Response<Full<Bytes>> {
Response::builder() Response::builder()
.header(header::CONTENT_TYPE, "image/png") .header(header::CONTENT_TYPE, "image/png")
.body(Body::from(assets::logo())) .body(Full::new(Bytes::from(assets::logo())))
.unwrap() .unwrap()
} }
fn handle_icon(&self) -> Response<Body> { fn handle_icon(&self) -> Response<Full<Bytes>> {
Response::builder() Response::builder()
.header(header::CONTENT_TYPE, "image/png") .header(header::CONTENT_TYPE, "image/png")
.body(Body::from(assets::icon())) .body(Full::new(Bytes::from(assets::icon())))
.unwrap() .unwrap()
} }
fn handle_home(&self) -> Response<Body> { fn handle_home(&self) -> Response<Full<Bytes>> {
let page = self.normal_page(html! { let page = self.normal_page(html! {
<div class="button-list"> <div class="button-list">
{ Self::button("Rojo Documentation", "https://rojo.space/docs") } { Self::button("Rojo Documentation", "https://rojo.space/docs") }
@ -68,11 +73,11 @@ impl UiService {
Response::builder() Response::builder()
.header(header::CONTENT_TYPE, "text/html") .header(header::CONTENT_TYPE, "text/html")
.body(Body::from(format!("<!DOCTYPE html>{}", page))) .body(Full::new(Bytes::from(format!("<!DOCTYPE html>{}", page))))
.unwrap() .unwrap()
} }
fn handle_show_instances(&self) -> Response<Body> { fn handle_show_instances(&self) -> Response<Full<Bytes>> {
let tree = self.serve_session.tree(); let tree = self.serve_session.tree();
let root_id = tree.get_root_id(); let root_id = tree.get_root_id();
@ -82,7 +87,7 @@ impl UiService {
Response::builder() Response::builder()
.header(header::CONTENT_TYPE, "text/html") .header(header::CONTENT_TYPE, "text/html")
.body(Body::from(format!("<!DOCTYPE html>{}", page))) .body(Full::new(Bytes::from(format!("<!DOCTYPE html>{}", page))))
.unwrap() .unwrap()
} }

View file

@ -1,11 +1,13 @@
use hyper::{header::CONTENT_TYPE, Body, Response, StatusCode}; use bytes::Bytes;
use http_body_util::Full;
use hyper::{header::CONTENT_TYPE, Response, StatusCode};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub fn msgpack_ok<T: Serialize>(value: T) -> Response<Body> { pub fn msgpack_ok<T: Serialize>(value: T) -> Response<Full<Bytes>> {
msgpack(value, StatusCode::OK) msgpack(value, StatusCode::OK)
} }
pub fn msgpack<T: Serialize>(value: T, code: StatusCode) -> Response<Body> { pub fn msgpack<T: Serialize>(value: T, code: StatusCode) -> Response<Full<Bytes>> {
let mut serialized = Vec::new(); let mut serialized = Vec::new();
let mut serializer = rmp_serde::Serializer::new(&mut serialized) let mut serializer = rmp_serde::Serializer::new(&mut serialized)
.with_human_readable() .with_human_readable()
@ -15,14 +17,14 @@ pub fn msgpack<T: Serialize>(value: T, code: StatusCode) -> Response<Body> {
return Response::builder() return Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR) .status(StatusCode::INTERNAL_SERVER_ERROR)
.header(CONTENT_TYPE, "text/plain") .header(CONTENT_TYPE, "text/plain")
.body(Body::from(err.to_string())) .body(Full::new(Bytes::from(err.to_string())))
.unwrap(); .unwrap();
}; };
Response::builder() Response::builder()
.status(code) .status(code)
.header(CONTENT_TYPE, "application/msgpack") .header(CONTENT_TYPE, "application/msgpack")
.body(Body::from(serialized)) .body(Full::new(Bytes::from(serialized)))
.unwrap() .unwrap()
} }
@ -45,14 +47,14 @@ pub fn deserialize_msgpack<'a, T: Deserialize<'a>>(
T::deserialize(&mut deserializer) T::deserialize(&mut deserializer)
} }
pub fn json<T: Serialize>(value: T, code: StatusCode) -> Response<Body> { pub fn json<T: Serialize>(value: T, code: StatusCode) -> Response<Full<Bytes>> {
let serialized = match serde_json::to_string(&value) { let serialized = match serde_json::to_string(&value) {
Ok(v) => v, Ok(v) => v,
Err(err) => { Err(err) => {
return Response::builder() return Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR) .status(StatusCode::INTERNAL_SERVER_ERROR)
.header(CONTENT_TYPE, "text/plain") .header(CONTENT_TYPE, "text/plain")
.body(Body::from(err.to_string())) .body(Full::new(Bytes::from(err.to_string())))
.unwrap(); .unwrap();
} }
}; };
@ -60,6 +62,6 @@ pub fn json<T: Serialize>(value: T, code: StatusCode) -> Response<Body> {
Response::builder() Response::builder()
.status(code) .status(code)
.header(CONTENT_TYPE, "application/json") .header(CONTENT_TYPE, "application/json")
.body(Body::from(serialized)) .body(Full::new(Bytes::from(serialized)))
.unwrap() .unwrap()
} }