This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new 56b5b38c2 feat(compiler): set thread_safe_pointer to false by default
and enhance ci (#3690)
56b5b38c2 is described below
commit 56b5b38c2e97e9c4cd95d691fdd2473590b31b4c
Author: Shawn Yang <[email protected]>
AuthorDate: Mon May 18 12:29:48 2026 +0800
feat(compiler): set thread_safe_pointer to false by default and enhance ci
(#3690)
BREAKING CHANGE: Rust IDL ref fields now generate Rc/RcWeak unless
thread_safe=true is set, which generates Arc/ArcWeak.
## Why?
Rust IDL ref fields do not need cross-thread ownership by default. Using
`Rc`/`RcWeak` as the default keeps generated Rust types aligned with the
non-thread-safe default while still allowing users to opt into
`Arc`/`ArcWeak` when cross-thread sharing is required.
## What does this PR do?
- Adds the `thread_safe_pointer` field option to the compiler protobuf
extension so protobuf IDL can opt Rust ref fields into `Arc`/`ArcWeak`.
- Updates Rust codegen so ref fields, weak refs, list element refs, map
value refs, and union payload refs default to `Rc`/`RcWeak` unless
`thread_safe=true` is set.
- Updates generated-code tests and Rust IDL roundtrip tests to validate
the new default pointer mapping and the thread-safe opt-in path.
- Refreshes compiler IDL docs for Fory IDL, protobuf IDL, and
FlatBuffers IDL with the new Rust pointer carrier behavior.
- Adds a dedicated Scala IDL CI job, enables warnings-as-errors for the
C++ example builds, and fixes AVX2 constant helpers used by UTF string
utilities.
## Related issues
## AI Contribution Checklist
- [ ] Substantial AI assistance was used in this PR: `yes` / `no`
- [ ] If `yes`, I included a completed [AI Contribution
Checklist](https://github.com/apache/fory/blob/main/AI_POLICY.md#9-contributor-checklist-for-ai-assisted-prs)
in this PR description and the required `AI Usage Disclosure`.
- [ ] If `yes`, my PR description includes the required `ai_review`
summary and screenshot evidence of the final clean AI review results
from both fresh reviewers on the current PR diff or current HEAD after
the latest code changes.
## Does this PR introduce any user-facing change?
- [x] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
---
.github/workflows/ci.yml | 28 +++++++++++
compiler/extension/fory_options.proto | 7 +++
compiler/fory_compiler/frontend/fdl/parser.py | 2 +-
compiler/fory_compiler/generators/rust.py | 33 ++++++------
.../fory_compiler/tests/test_generated_code.py | 37 +++++++++++++-
cpp/fory/util/string_util.cc | 12 +++--
cpp/fory/util/string_util.h | 2 +-
docs/compiler/flatbuffers-idl.md | 19 ++++---
docs/compiler/protobuf-idl.md | 22 ++++----
docs/compiler/schema-idl.md | 24 ++++++---
examples/cpp/hello_row/run.sh | 2 +-
examples/cpp/hello_world/run.sh | 2 +-
.../idl_tests/rust/tests/idl_roundtrip.rs | 58 +++++++++++-----------
13 files changed, 170 insertions(+), 78 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 325336d81..181e4d7ca 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -629,6 +629,34 @@ jobs:
mvn -T16 --no-transfer-progress clean install -DskipTests
-Dmaven.javadoc.skip=true -Dmaven.source.skip=true
cd fory-core
mvn -T16 --no-transfer-progress test
-Dtest=org.apache.fory.xlang.ScalaXlangTest
+
+ scala_idl:
+ name: Scala IDL Tests
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v5
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: 21
+ distribution: "temurin"
+ cache: sbt
+ - name: Set up Python 3.11
+ uses: actions/setup-python@v5
+ with:
+ python-version: 3.11
+ - name: Cache Maven local repository
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2/repository
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+ - uses: sbt/setup-sbt@1cad58d595b729a71ca2254cdf5b43dd6f42d4bb # v1.1.18
+ - name: Install Fory Java
+ run: |
+ cd java
+ mvn -T16 --no-transfer-progress clean install -DskipTests
-Dmaven.javadoc.skip=true -Dmaven.source.skip=true
- name: Run Scala IDL Tests
run: ./integration_tests/idl_tests/run_scala_tests.sh
diff --git a/compiler/extension/fory_options.proto
b/compiler/extension/fory_options.proto
index 1fbf72e26..62ae96802 100644
--- a/compiler/extension/fory_options.proto
+++ b/compiler/extension/fory_options.proto
@@ -177,6 +177,13 @@ message ForyFieldOptions {
// Requires ref=true or a ref modifier. Ignored by Java/Python/Go.
// Default: false
optional bool weak_ref = 4;
+
+ // Generate thread-safe Rust pointer carriers for ref fields.
+ // When true, Rust codegen uses Arc/ArcWeak instead of Rc/RcWeak.
+ // This does not change the wire format and does not make the referenced
+ // value itself thread-safe.
+ // Default: false
+ optional bool thread_safe_pointer = 5;
}
extend google.protobuf.FieldOptions { optional ForyFieldOptions fory = 50001; }
diff --git a/compiler/fory_compiler/frontend/fdl/parser.py
b/compiler/fory_compiler/frontend/fdl/parser.py
index 8ae5a93d8..90771dcf9 100644
--- a/compiler/fory_compiler/frontend/fdl/parser.py
+++ b/compiler/fory_compiler/frontend/fdl/parser.py
@@ -771,7 +771,7 @@ class Parser:
return options
def parse_ref_options(self, name: str) -> dict:
- """Parse ref keyword options: ref(weak=true, thread_safe=false)."""
+ """Parse ref keyword options such as ref(weak=true,
thread_safe=false)."""
if not self.check(TokenType.LPAREN):
return {}
self.consume(TokenType.LPAREN, "Expected '(' after ref")
diff --git a/compiler/fory_compiler/generators/rust.py
b/compiler/fory_compiler/generators/rust.py
index 42fe2aae7..943a549ad 100644
--- a/compiler/fory_compiler/generators/rust.py
+++ b/compiler/fory_compiler/generators/rust.py
@@ -381,6 +381,7 @@ class RustGenerator(BaseGenerator):
for field in union.fields:
variant_name = self.to_pascal_case(field.name)
+ pointer_type = self.get_field_pointer_type(field)
variant_type = self.generate_type(
field.field_type,
nullable=False,
@@ -388,7 +389,7 @@ class RustGenerator(BaseGenerator):
element_optional=field.element_optional,
element_ref=field.element_ref,
parent_stack=parent_stack,
- pointer_type="::std::sync::Arc",
+ pointer_type=pointer_type,
)
lines.append(f" #[fory(id = {field.number})]")
payload_attr = self.get_payload_field_attr(field)
@@ -624,16 +625,7 @@ class RustGenerator(BaseGenerator):
if attrs:
lines.append(f"#[fory({', '.join(attrs)})]")
- if isinstance(field.field_type, ListType) and field.element_ref:
- ref_options = field.element_ref_options
- weak_ref = ref_options.get("weak_ref") is True
- elif isinstance(field.field_type, MapType) and
field.field_type.value_ref:
- ref_options = field.field_type.value_ref_options
- weak_ref = ref_options.get("weak_ref") is True
- else:
- ref_options = field.ref_options
- weak_ref = ref_options.get("weak_ref") is True
- pointer_type = self.get_pointer_type(ref_options, weak_ref)
+ pointer_type = self.get_field_pointer_type(field)
rust_type = self.generate_type(
field.field_type,
nullable=field.optional,
@@ -739,7 +731,7 @@ class RustGenerator(BaseGenerator):
element_optional: bool = False,
element_ref: bool = False,
parent_stack: Optional[List[Message]] = None,
- pointer_type: str = "::std::sync::Arc",
+ pointer_type: str = "::std::rc::Rc",
) -> str:
"""Generate Rust type string."""
if isinstance(field_type, PrimitiveType):
@@ -855,12 +847,21 @@ class RustGenerator(BaseGenerator):
return True
return False
+ def get_field_pointer_type(self, field: Field) -> str:
+ if isinstance(field.field_type, ListType) and field.element_ref:
+ ref_options = field.element_ref_options
+ elif isinstance(field.field_type, MapType) and
field.field_type.value_ref:
+ ref_options = field.field_type.value_ref_options
+ else:
+ ref_options = field.ref_options
+ weak_ref = ref_options.get("weak_ref") is True
+ return self.get_pointer_type(ref_options, weak_ref)
+
def get_pointer_type(self, ref_options: dict, weak_ref: bool = False) ->
str:
"""Determine pointer type for ref tracking based on field options."""
- thread_safe = ref_options.get("thread_safe_pointer")
- if thread_safe is False:
- return "::fory::RcWeak" if weak_ref else "::std::rc::Rc"
- return "::fory::ArcWeak" if weak_ref else "::std::sync::Arc"
+ if ref_options.get("thread_safe_pointer") is True:
+ return "::fory::ArcWeak" if weak_ref else "::std::sync::Arc"
+ return "::fory::RcWeak" if weak_ref else "::std::rc::Rc"
def generate_registration(self) -> List[str]:
"""Generate the Fory registration function."""
diff --git a/compiler/fory_compiler/tests/test_generated_code.py
b/compiler/fory_compiler/tests/test_generated_code.py
index 5b5ea2df8..b855c1149 100644
--- a/compiler/fory_compiler/tests/test_generated_code.py
+++ b/compiler/fory_compiler/tests/test_generated_code.py
@@ -460,6 +460,39 @@ def test_generated_code_map_types_equivalent():
assert "SharedWeak<MapValue>" in cpp_output
+def test_rust_generated_ref_pointer_default_and_thread_safe_option():
+ schema = parse_fdl(
+ dedent(
+ """
+ package gen;
+
+ message Node {
+ string value = 1;
+ }
+
+ message Holder {
+ ref Node default_ref = 1;
+ ref(thread_safe=true) Node thread_safe_ref = 2;
+ ref(weak=true) Node default_weak_ref = 3;
+ ref(weak=true, thread_safe=true) Node thread_safe_weak_ref = 4;
+ list<ref Node> default_ref_list = 5;
+ list<ref(thread_safe=true) Node> thread_safe_ref_list = 6;
+ }
+ """
+ )
+ )
+ rust_output = render_files(generate_files(schema, RustGenerator))
+ assert "pub default_ref: ::std::rc::Rc<Node>," in rust_output
+ assert "pub thread_safe_ref: ::std::sync::Arc<Node>," in rust_output
+ assert "pub default_weak_ref: ::fory::RcWeak<Node>," in rust_output
+ assert "pub thread_safe_weak_ref: ::fory::ArcWeak<Node>," in rust_output
+ assert "pub default_ref_list: ::std::vec::Vec<::std::rc::Rc<Node>>," in
rust_output
+ assert (
+ "pub thread_safe_ref_list: ::std::vec::Vec<::std::sync::Arc<Node>>,"
+ in rust_output
+ )
+
+
def test_generated_code_nested_messages_equivalent():
fdl = dedent(
"""
@@ -709,7 +742,7 @@ def test_generated_code_tree_ref_options_equivalent():
assert_all_languages_equal(schemas)
rust_output = render_files(generate_files(schemas["fdl"], RustGenerator))
- assert "ArcWeak<TreeNode>" in rust_output
+ assert "RcWeak<TreeNode>" in rust_output
cpp_output = render_files(generate_files(schemas["fdl"], CppGenerator))
assert "SharedWeak<TreeNode>" in cpp_output
@@ -1079,6 +1112,6 @@ def test_rust_generated_code_uses_absolute_paths():
in rust_output
)
assert "pub payload: ::std::boxed::Box<dyn ::std::any::Any>," in
rust_output
- assert "pub parent: ::fory::ArcWeak<String>," in rust_output
+ assert "pub parent: ::fory::RcWeak<String>," in rust_output
assert "pub fn register_types(fory: &mut ::fory::Fory)" in rust_output
assert "static FORY: ::std::sync::OnceLock<::fory::Fory>" in rust_output
diff --git a/cpp/fory/util/string_util.cc b/cpp/fory/util/string_util.cc
index 2fb36ead6..88e502586 100644
--- a/cpp/fory/util/string_util.cc
+++ b/cpp/fory/util/string_util.cc
@@ -159,10 +159,14 @@ FORY_TARGET_AVX2_ATTR std::string utf16_to_utf8(const
std::u16string &utf16,
const __m256i limit1 = _mm256_set1_epi16(0x80);
const __m256i limit2 = _mm256_set1_epi16(0x800);
- const __m256i surrogate_high_start = _mm256_set1_epi16(0xD800);
- const __m256i surrogate_high_end = _mm256_set1_epi16(0xDBFF);
- const __m256i surrogate_low_start = _mm256_set1_epi16(0xDC00);
- const __m256i surrogate_low_end = _mm256_set1_epi16(0xDFFF);
+ const __m256i surrogate_high_start =
+ _mm256_set1_epi16(static_cast<int16_t>(0xD800));
+ const __m256i surrogate_high_end =
+ _mm256_set1_epi16(static_cast<int16_t>(0xDBFF));
+ const __m256i surrogate_low_start =
+ _mm256_set1_epi16(static_cast<int16_t>(0xDC00));
+ const __m256i surrogate_low_end =
+ _mm256_set1_epi16(static_cast<int16_t>(0xDFFF));
char buffer[64]; // Buffer to hold temporary UTF-8 bytes
char *output = buffer;
diff --git a/cpp/fory/util/string_util.h b/cpp/fory/util/string_util.h
index 83afc3d18..7f5935b0a 100644
--- a/cpp/fory/util/string_util.h
+++ b/cpp/fory/util/string_util.h
@@ -277,7 +277,7 @@ inline bool is_ascii(const char *data, size_t length) {
constexpr size_t VECTOR_SIZE = 32;
const auto *ptr = reinterpret_cast<const __m256i *>(data);
const auto *end = ptr + length / VECTOR_SIZE;
- const __m256i mask = _mm256_set1_epi8(0x80);
+ const __m256i mask = _mm256_set1_epi8(static_cast<char>(0x80));
for (; ptr < end; ++ptr) {
__m256i vec = _mm256_loadu_si256(ptr);
diff --git a/docs/compiler/flatbuffers-idl.md b/docs/compiler/flatbuffers-idl.md
index c8e794570..90600640b 100644
--- a/docs/compiler/flatbuffers-idl.md
+++ b/docs/compiler/flatbuffers-idl.md
@@ -135,17 +135,20 @@ FlatBuffers metadata attributes use `key:value`. For
Fory-specific options, use
### Supported Field Attributes
-| FlatBuffers Attribute | Effect in Fory
|
-| -------------------------------- |
----------------------------------------------------- |
-| `fory_ref:true` | Enable reference tracking for the field
|
-| `fory_nullable:true` | Mark field optional/nullable
|
-| `fory_weak_ref:true` | Enable weak reference semantics and
implies `ref` |
-| `fory_thread_safe_pointer:false` | For ref fields, select non-thread-safe
pointer flavor |
+| FlatBuffers Attribute | Effect in Fory
|
+| ------------------------------- |
--------------------------------------------------------------------------------
|
+| `fory_ref:true` | Enable reference tracking for the field
|
+| `fory_nullable:true` | Mark field optional/nullable
|
+| `fory_weak_ref:true` | Enable weak reference semantics and
implies `ref` |
+| `fory_thread_safe_pointer:true` | For ref fields, select Rust
`Arc`/`ArcWeak` instead of the default `Rc`/`RcWeak` |
Semantics:
- `fory_weak_ref:true` implies `ref`.
-- `fory_thread_safe_pointer` only takes effect when the field is ref-tracked.
+- `fory_thread_safe_pointer` defaults to `false`, only takes effect when the
field
+ is ref-tracked, and does not change the wire format.
+- In Rust codegen, `fory_weak_ref:true` uses `RcWeak` by default and switches
to
+ `ArcWeak` only when `fory_thread_safe_pointer:true` is also set.
- For list fields, `fory_ref:true` applies to list elements.
Example:
@@ -154,7 +157,7 @@ Example:
table Node {
parent: Node (fory_weak_ref: true);
children: [Node] (fory_ref: true);
- cached: Node (fory_ref: true, fory_thread_safe_pointer: false);
+ cached: Node (fory_ref: true, fory_thread_safe_pointer: true);
}
```
diff --git a/docs/compiler/protobuf-idl.md b/docs/compiler/protobuf-idl.md
index 58bb92bf6..0105a8955 100644
--- a/docs/compiler/protobuf-idl.md
+++ b/docs/compiler/protobuf-idl.md
@@ -229,14 +229,14 @@ message TreeNode {
### Field-Level Options
-| Option | Type | Description
|
-| ---------------------------- | ------ |
----------------------------------------------------- |
-| `(fory).ref` | bool | Enable reference tracking for this
field |
-| `(fory).nullable` | bool | Treat field as nullable (`optional`)
|
-| `(fory).weak_ref` | bool | Generate weak pointer semantics
(C++/Rust codegen) |
-| `(fory).thread_safe_pointer` | bool | Rust pointer flavor for ref fields
(`Arc` vs `Rc`) |
-| `(fory).deprecated` | bool | Mark field as deprecated
|
-| `(fory).type` | string | Primitive override for tagged 64-bit
integer encoding |
+| Option | Type | Description
|
+| ---------------------------- | ------ |
--------------------------------------------------------------------------- |
+| `(fory).ref` | bool | Enable reference tracking for this
field |
+| `(fory).nullable` | bool | Treat field as nullable (`optional`)
|
+| `(fory).weak_ref` | bool | Generate weak pointer semantics
(C++/Rust codegen) |
+| `(fory).thread_safe_pointer` | bool | Use Rust `Arc`/`ArcWeak` for ref
fields; default `false` uses `Rc`/`RcWeak` |
+| `(fory).deprecated` | bool | Mark field as deprecated
|
+| `(fory).type` | string | Primitive override for tagged 64-bit
integer encoding |
Reference option behavior:
@@ -244,12 +244,16 @@ Reference option behavior:
- For `repeated` fields, `(fory).ref = true` applies to list elements.
- For `map<K, V>` fields, `(fory).ref = true` applies to map values.
- `weak_ref` and `thread_safe_pointer` are codegen hints for C++/Rust.
+- `thread_safe_pointer` defaults to `false`; it changes only the generated Rust
+ pointer carrier and does not change the wire format.
+- In Rust codegen, `(fory).weak_ref = true` uses `RcWeak` by default and
switches
+ to `ArcWeak` only when `(fory).thread_safe_pointer = true`.
### Option Examples by Shape
```protobuf
message Graph {
- Node root = 1 [(fory).ref = true, (fory).thread_safe_pointer = false];
+ Node root = 1 [(fory).ref = true, (fory).thread_safe_pointer = true];
repeated Node nodes = 2 [(fory).ref = true];
map<string, Node> cache = 3 [(fory).ref = true];
Node parent = 4 [(fory).weak_ref = true];
diff --git a/docs/compiler/schema-idl.md b/docs/compiler/schema-idl.md
index 50364d6c2..799b8fb0e 100644
--- a/docs/compiler/schema-idl.md
+++ b/docs/compiler/schema-idl.md
@@ -966,16 +966,28 @@ message Node {
| Java | `Node parent` | `Node parent` with `@Ref` |
| Python | `parent: Node` | `parent: Node = pyfory.field(ref=True)` |
| Go | `Parent Node` | `Parent *Node` with `fory:"ref"` |
-| Rust | `parent: Node` | `parent: Arc<Node>` |
+| Rust | `parent: Node` | `parent: Rc<Node>` |
| C++ | `Node parent` | `std::shared_ptr<Node> parent` |
| JavaScript | `parent: Node` | `parent: Node` (no ref distinction) |
| Dart | `Node parent` | `Node parent` with `@ForyField(ref: true)` |
| Scala | `parent: Node` | `@Ref parent: Node` |
-Rust uses `Arc` by default; use `ref(thread_safe=false)` or `ref(weak=true)`
-to customize pointer types. For protobuf option syntax, see
+Rust uses `Rc` and `RcWeak` by default for ref-tracked fields. Use
+`ref(thread_safe=true)` when the generated Rust type must use `Arc` or
+`ArcWeak` for cross-thread shared ownership. This setting is a Rust codegen
+carrier choice; it does not change the wire format or make the referenced value
+itself thread-safe. For protobuf option syntax, see
[Protocol Buffers IDL Support](protobuf-idl.md#field-level-options).
+Rust pointer carrier mapping:
+
+| Fory IDL | Rust type |
+| ---------------------------------------------- | --------------- |
+| `ref Node parent` | `Rc<Node>` |
+| `ref(thread_safe=true) Node parent` | `Arc<Node>` |
+| `ref(weak=true) Node parent` | `RcWeak<Node>` |
+| `ref(weak=true, thread_safe=true) Node parent` | `ArcWeak<Node>` |
+
#### `list`
Marks the field as an ordered collection:
@@ -1022,10 +1034,10 @@ accepted as an alias for `list`.
| ----------------------- | ---------------------------------- |
--------------------- | ----------------------- | --------------------- |
----------------------------------------- |
------------------------------------------------------------- |
---------------------- |
| `optional list<string>` | `@Nullable List<String>` |
`Optional[List[str]]` | `[]string` + `nullable` | `Option<Vec<String>>` |
`std::optional<std::vector<std::string>>` | `List<String>?`
| `Option[List[String]]` |
| `list<optional string>` | `List<String>` (nullable elements) |
`List[Optional[str]]` | `[]*string` | `Vec<Option<String>>` |
`std::vector<std::optional<std::string>>` | `List<String?>`
| `List[Option[String]]` |
-| `list<ref User>` | `List<@Ref User>` | `List[User]`
| `[]*User` + `ref=false` | `Vec<Arc<User>>` |
`std::vector<std::shared_ptr<User>>` | `List<User>` + `@ListField(element:
DeclaredType(ref: true))` | `List[User @Ref]` |
+| `list<ref User>` | `List<@Ref User>` | `List[User]`
| `[]*User` + `ref=false` | `Vec<Rc<User>>` |
`std::vector<std::shared_ptr<User>>` | `List<User>` + `@ListField(element:
DeclaredType(ref: true))` | `List[User @Ref]` |
-Use `ref(thread_safe=false)` in Fory IDL (or `[(fory).thread_safe_pointer =
false]` in protobuf)
-to generate `Rc` instead of `Arc` in Rust.
+Use `ref(thread_safe=true)` in Fory IDL (or `[(fory).thread_safe_pointer =
true]` in protobuf)
+to generate `Arc` instead of `Rc` in Rust.
## Field Numbers
diff --git a/examples/cpp/hello_row/run.sh b/examples/cpp/hello_row/run.sh
index 68ce2d9ba..687470fcb 100755
--- a/examples/cpp/hello_row/run.sh
+++ b/examples/cpp/hello_row/run.sh
@@ -41,7 +41,7 @@ cd "${BUILD_DIR}"
# Configure
echo "Configuring with CMake..."
-cmake .. -DCMAKE_BUILD_TYPE=Release
+cmake .. -DCMAKE_BUILD_TYPE=Release -DFORY_WARNINGS_AS_ERRORS=ON
# Build
echo ""
diff --git a/examples/cpp/hello_world/run.sh b/examples/cpp/hello_world/run.sh
index ccaaf0ff8..c6929811d 100755
--- a/examples/cpp/hello_world/run.sh
+++ b/examples/cpp/hello_world/run.sh
@@ -41,7 +41,7 @@ cd "${BUILD_DIR}"
# Configure
echo "Configuring with CMake..."
-cmake .. -DCMAKE_BUILD_TYPE=Release
+cmake .. -DCMAKE_BUILD_TYPE=Release -DFORY_WARNINGS_AS_ERRORS=ON
# Build
echo ""
diff --git a/integration_tests/idl_tests/rust/tests/idl_roundtrip.rs
b/integration_tests/idl_tests/rust/tests/idl_roundtrip.rs
index 1e1b7b1c2..5d28da0f9 100644
--- a/integration_tests/idl_tests/rust/tests/idl_roundtrip.rs
+++ b/integration_tests/idl_tests/rust/tests/idl_roundtrip.rs
@@ -16,11 +16,11 @@
// under the License.
use std::collections::HashMap;
-use std::sync::Arc;
+use std::rc::Rc;
use std::{env, fs};
use chrono::NaiveDate;
-use fory::{ArcWeak, BFloat16, Float16, Fory};
+use fory::{BFloat16, Float16, Fory, RcWeak};
use idl_tests::generated::addressbook::{
self,
person::{PhoneNumber, PhoneType},
@@ -638,31 +638,31 @@ fn assert_any_holder(holder: &AnyHolder) {
}
fn build_tree() -> tree::TreeNode {
- let mut child_a = Arc::new(tree::TreeNode {
+ let mut child_a = Rc::new(tree::TreeNode {
id: "child-a".to_string(),
name: "child-a".to_string(),
children: vec![],
parent: None,
});
- let mut child_b = Arc::new(tree::TreeNode {
+ let mut child_b = Rc::new(tree::TreeNode {
id: "child-b".to_string(),
name: "child-b".to_string(),
children: vec![],
parent: None,
});
- let child_a_weak = ArcWeak::from(&child_a);
- let child_b_weak = ArcWeak::from(&child_b);
- Arc::get_mut(&mut child_a).expect("child a unique").parent =
Some(child_b_weak);
- Arc::get_mut(&mut child_b).expect("child b unique").parent =
Some(child_a_weak);
+ let child_a_weak = RcWeak::from(&child_a);
+ let child_b_weak = RcWeak::from(&child_b);
+ Rc::get_mut(&mut child_a).expect("child a unique").parent =
Some(child_b_weak);
+ Rc::get_mut(&mut child_b).expect("child b unique").parent =
Some(child_a_weak);
tree::TreeNode {
id: "root".to_string(),
name: "root".to_string(),
children: vec![
- Arc::clone(&child_a),
- Arc::clone(&child_a),
- Arc::clone(&child_b),
+ Rc::clone(&child_a),
+ Rc::clone(&child_a),
+ Rc::clone(&child_b),
],
parent: None,
}
@@ -670,8 +670,8 @@ fn build_tree() -> tree::TreeNode {
fn assert_tree(root: &tree::TreeNode) {
assert_eq!(root.children.len(), 3);
- assert!(Arc::ptr_eq(&root.children[0], &root.children[1]));
- assert!(!Arc::ptr_eq(&root.children[0], &root.children[2]));
+ assert!(Rc::ptr_eq(&root.children[0], &root.children[1]));
+ assert!(!Rc::ptr_eq(&root.children[0], &root.children[2]));
let parent_a = root.children[0]
.parent
.as_ref()
@@ -684,36 +684,36 @@ fn assert_tree(root: &tree::TreeNode) {
.expect("child b parent")
.upgrade()
.expect("upgrade child b parent");
- assert!(Arc::ptr_eq(&parent_a, &root.children[2]));
- assert!(Arc::ptr_eq(&parent_b, &root.children[0]));
+ assert!(Rc::ptr_eq(&parent_a, &root.children[2]));
+ assert!(Rc::ptr_eq(&parent_b, &root.children[0]));
}
fn build_graph() -> graph::Graph {
- let mut node_a = Arc::new(graph::Node {
+ let mut node_a = Rc::new(graph::Node {
id: "node-a".to_string(),
out_edges: vec![],
in_edges: vec![],
});
- let mut node_b = Arc::new(graph::Node {
+ let mut node_b = Rc::new(graph::Node {
id: "node-b".to_string(),
out_edges: vec![],
in_edges: vec![],
});
- let edge = Arc::new(graph::Edge {
+ let edge = Rc::new(graph::Edge {
id: "edge-1".to_string(),
weight: 1.5_f32,
- from: Some(ArcWeak::from(&node_a)),
- to: Some(ArcWeak::from(&node_b)),
+ from: Some(RcWeak::from(&node_a)),
+ to: Some(RcWeak::from(&node_b)),
});
- Arc::get_mut(&mut node_a).expect("node a unique").out_edges =
vec![Arc::clone(&edge)];
- Arc::get_mut(&mut node_a).expect("node a unique").in_edges =
vec![Arc::clone(&edge)];
- Arc::get_mut(&mut node_b).expect("node b unique").in_edges =
vec![Arc::clone(&edge)];
+ Rc::get_mut(&mut node_a).expect("node a unique").out_edges =
vec![Rc::clone(&edge)];
+ Rc::get_mut(&mut node_a).expect("node a unique").in_edges =
vec![Rc::clone(&edge)];
+ Rc::get_mut(&mut node_b).expect("node b unique").in_edges =
vec![Rc::clone(&edge)];
graph::Graph {
- nodes: vec![Arc::clone(&node_a), Arc::clone(&node_b)],
- edges: vec![Arc::clone(&edge)],
+ nodes: vec![Rc::clone(&node_a), Rc::clone(&node_b)],
+ edges: vec![Rc::clone(&edge)],
}
}
@@ -723,8 +723,8 @@ fn assert_graph(value: &graph::Graph) {
let node_a = &value.nodes[0];
let node_b = &value.nodes[1];
let edge = &value.edges[0];
- assert!(Arc::ptr_eq(&node_a.out_edges[0], &node_a.in_edges[0]));
- assert!(Arc::ptr_eq(&node_a.out_edges[0], edge));
+ assert!(Rc::ptr_eq(&node_a.out_edges[0], &node_a.in_edges[0]));
+ assert!(Rc::ptr_eq(&node_a.out_edges[0], edge));
let from = edge
.from
.as_ref()
@@ -737,8 +737,8 @@ fn assert_graph(value: &graph::Graph) {
.expect("edge to")
.upgrade()
.expect("upgrade to");
- assert!(Arc::ptr_eq(&from, node_a));
- assert!(Arc::ptr_eq(&to, node_b));
+ assert!(Rc::ptr_eq(&from, node_a));
+ assert!(Rc::ptr_eq(&to, node_b));
}
#[test]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]