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-site.git
commit 8ae5b90d348caa5e8f6115e4cfc7fc69415711e9 Author: chaokunyang <[email protected]> AuthorDate: Fri Feb 6 07:11:55 2026 +0000 🔄 synced local 'docs/guide/' with remote 'docs/guide/' --- docs/guide/DEVELOPMENT.md | 93 +++++++++++---------------- docs/guide/cpp/cross-language.md | 4 +- docs/guide/cpp/type-registration.md | 8 +-- docs/guide/go/cross-language.md | 4 +- docs/guide/go/type-registration.md | 4 +- docs/guide/java/cross-language.md | 2 +- docs/guide/rust/cross-language.md | 2 +- docs/guide/rust/field-configuration.md | 36 +++++------ docs/guide/xlang/field-nullability.md | 9 ++- docs/guide/xlang/field-reference-tracking.md | 23 ++++--- docs/guide/xlang/getting-started.md | 30 +++++---- docs/guide/xlang/index.md | 43 ++++++++++++- docs/guide/xlang/serialization.md | 96 +++++++++++++++------------- docs/guide/xlang/troubleshooting.md | 2 +- docs/guide/xlang/zero-copy.md | 18 +++--- 15 files changed, 207 insertions(+), 167 deletions(-) diff --git a/docs/guide/DEVELOPMENT.md b/docs/guide/DEVELOPMENT.md index ed8633f432..8fa9fec92f 100644 --- a/docs/guide/DEVELOPMENT.md +++ b/docs/guide/DEVELOPMENT.md @@ -21,93 +21,83 @@ license: | ## How to build Apache Fory™ -Please checkout the source tree from https://github.com/apache/fory. +Clone the source tree from https://github.com/apache/fory. ### Build Apache Fory™ Java ```bash cd java -mvn clean compile -DskipTests +mvn -T16 package ``` #### Environment Requirements -- java 1.8+ -- maven 3.6.3+ +- JDK 17+ +- Maven 3.6.3+ ### Build Apache Fory™ Python ```bash cd python -# Uninstall numpy first so that when we install pyarrow, it will install the correct numpy version automatically. -# For Python versions less than 3.13, numpy 2 is not currently supported. -pip uninstall -y numpy -# Install necessary environment for Python < 3.13. -pip install pyarrow Cython wheel pytest -# pip install pyarrow Cython wheel pytest pip install -v -e . + +# Optional: build Cython extension (replace X.Y with your Python version) +bazel build //:cp_fory_so --@rules_python//python/config_settings:python_version=X.Y ``` #### Environment Requirements -- python 3.6+ +- CPython 3.8+ +- Bazel 8+ (required when building Cython extensions) ### Build Apache Fory™ C++ -Build fory row format: - -```bash -bazel build //cpp/fory/row:fory_row_format -``` - -Build fory row format encoder: - ```bash -bazel build //cpp/fory/encoder:fory_encoder +cd cpp +bazel build //cpp/... ``` #### Environment Requirements -- compilers with C++17 support -- bazel 6.3.2 +- C++17 compiler +- Bazel 8+ -### Build Apache Fory™ GoLang +### Build Apache Fory™ Go ```bash cd go/fory -# run test go test -v ./... -# run xlang test -go test -v fory_xlang_test.go +``` + +Run Go xlang tests from Java test module: + +```bash +cd java +mvn -T16 install -DskipTests +cd fory-core +FORY_GO_JAVA_CI=1 ENABLE_FORY_DEBUG_OUTPUT=1 mvn test -Dtest=org.apache.fory.xlang.GoXlangTest ``` #### Environment Requirements -- go 1.13+ +- Go 1.24+ ### Build Apache Fory™ Rust ```bash cd rust -# build cargo build -# run test -cargo test -# run specific test -cargo test -p tests --test $test_file $test_method -# run specific test under subdirectory -cargo test --test mod $dir$::$test_file::$test_method -# debug specific test under subdirectory and get backtrace -RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 cargo test --test mod $dir$::$test_file::$test_method -# inspect generated code by fory derive macro -cargo expand --test mod $mod$::$file$ > expanded.rs +cargo test --features tests + +# Debug a specific test +RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 ENABLE_FORY_DEBUG_OUTPUT=1 \ + cargo test --test mod $dir$::$test_file::$test_method -- --nocapture ``` #### Environment Requirements -```bash -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -``` +- Rust toolchain via rustup +- `cargo-expand` (optional, for macro expansion debugging) ### Build Apache Fory™ JavaScript @@ -115,32 +105,27 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh cd javascript npm install -# run build npm run build -# run test -npm run test +node ./node_modules/.bin/jest --ci --reporters=default --reporters=jest-junit ``` #### Environment Requirements -- node 14+ -- npm 8+ +- Node.js (LTS) +- npm ### Lint Markdown Docs ```bash -# Install prettier globally -npm install -g prettier - -# Fix markdown files -prettier --write "**/*.md" +cd docs +npx prettier --write "**/*.md" ``` #### Environment Requirements -- node 14+ -- npm 8+ +- Node.js (LTS) +- npm ## Contributing -For more information, please refer to [How to contribute to Apache Fory™](https://github.com/apache/fory/blob/main/CONTRIBUTING.md). +For contribution details, see [How to contribute to Apache Fory™](https://github.com/apache/fory/blob/main/CONTRIBUTING.md). diff --git a/docs/guide/cpp/cross-language.md b/docs/guide/cpp/cross-language.md index d0845e32e2..5632d45b2c 100644 --- a/docs/guide/cpp/cross-language.md +++ b/docs/guide/cpp/cross-language.md @@ -122,7 +122,7 @@ class Message: headers: dict[str, str] payload: bytes -fory = pyfory.Fory() +fory = pyfory.Fory(xlang=True) fory.register(Message, type_id=100) # Same ID as C++ with open("message.bin", "rb") as f: @@ -171,7 +171,7 @@ print(f"Timestamp: {msg.timestamp}") ## Field Order Requirements -**Critical:** Field will be sorted by their snake_cased field name, converted name must be considten across langauges +**Critical:** Fields are sorted by snake_case field name. The converted names must match across languages. ### C++ diff --git a/docs/guide/cpp/type-registration.md b/docs/guide/cpp/type-registration.md index 99a5ca599f..4b77f80955 100644 --- a/docs/guide/cpp/type-registration.md +++ b/docs/guide/cpp/type-registration.md @@ -137,7 +137,7 @@ For cross-language compatibility, ensure: ### Java ```java -Fory fory = Fory.builder().build(); +Fory fory = Fory.builder().withXlang(true).build(); fory.register(Person.class, 100); fory.register(Address.class, 101); ``` @@ -147,9 +147,9 @@ fory.register(Address.class, 101); ```python import pyfory -fory = pyfory.Fory() -fory.register(Person, 100) -fory.register(Address, 101) +fory = pyfory.Fory(xlang=True) +fory.register(Person, type_id=100) +fory.register(Address, type_id=101) ``` ### C++ diff --git a/docs/guide/go/cross-language.md b/docs/guide/go/cross-language.md index 381597d8fa..ecf44025fc 100644 --- a/docs/guide/go/cross-language.md +++ b/docs/guide/go/cross-language.md @@ -69,7 +69,7 @@ class User: id: pyfory.Int64Type name: str -fory = pyfory.Fory() +fory = pyfory.Fory(xlang=True) fory.register(User, type_id=1) user = fory.deserialize(data) ``` @@ -161,7 +161,7 @@ class Message: content: str timestamp: pyfory.Int64Type -fory = pyfory.Fory() +fory = pyfory.Fory(xlang=True) fory.register(Message, type_id=1) msg = Message(id=1, content="Hello from Python", timestamp=1234567890) diff --git a/docs/guide/go/type-registration.md b/docs/guide/go/type-registration.md index c8236b734e..51425ec30d 100644 --- a/docs/guide/go/type-registration.md +++ b/docs/guide/go/type-registration.md @@ -214,7 +214,9 @@ fory.register(User, typename="example.User") **Rust**: ```rust -#[derive(Fory)] +use fory::{Fory, ForyObject}; + +#[derive(ForyObject)] struct User { id: i64, name: String, diff --git a/docs/guide/java/cross-language.md b/docs/guide/java/cross-language.md index e38160f095..c9421245fc 100644 --- a/docs/guide/java/cross-language.md +++ b/docs/guide/java/cross-language.md @@ -112,7 +112,7 @@ class Person: age: pyfory.int32 # Create Fory in xlang mode -fory = pyfory.Fory(ref=True) +fory = pyfory.Fory(xlang=True, ref=True) # Register with the SAME name as Java fory.register_type(Person, typename="example.Person") diff --git a/docs/guide/rust/cross-language.md b/docs/guide/rust/cross-language.md index 4245a56c80..fb0ff53776 100644 --- a/docs/guide/rust/cross-language.md +++ b/docs/guide/rust/cross-language.md @@ -121,7 +121,7 @@ class Person: name: str age: pyfory.int32 -fory = pyfory.Fory(ref=True) +fory = pyfory.Fory(xlang=True, ref=True) fory.register_type(Person, type_id=100) # Same ID as Rust person = fory.deserialize(bytes_from_rust) diff --git a/docs/guide/rust/field-configuration.md b/docs/guide/rust/field-configuration.md index a42e4ab426..0f9e1be2ef 100644 --- a/docs/guide/rust/field-configuration.md +++ b/docs/guide/rust/field-configuration.md @@ -36,9 +36,9 @@ Apache Fory™ provides the `#[fory(...)]` attribute macro to specify optional f The `#[fory(...)]` attribute is placed on individual struct fields: ```rust -use fory::Fory; +use fory::ForyObject; -#[derive(Fory)] +#[derive(ForyObject)] struct Person { #[fory(id = 0)] name: String, @@ -60,7 +60,7 @@ Multiple options are separated by commas. Assigns a numeric ID to a field to minimize struct field meta size overhead: ```rust -#[derive(Fory)] +#[derive(ForyObject)] struct User { #[fory(id = 0)] id: i64, @@ -91,7 +91,7 @@ struct User { Excludes a field from serialization: ```rust -#[derive(Fory)] +#[derive(ForyObject)] struct User { #[fory(id = 0)] id: i64, @@ -113,7 +113,7 @@ Controls whether null flags are written for fields: ```rust use fory::{Fory, RcWeak}; -#[derive(Fory)] +#[derive(ForyObject)] struct Record { // RcWeak is nullable by default, override to non-nullable #[fory(id = 0, nullable = false)] @@ -143,7 +143,7 @@ Controls per-field reference tracking for shared ownership types: use std::rc::Rc; use std::sync::Arc; -#[derive(Fory)] +#[derive(ForyObject)] struct Container { // Enable reference tracking (default for Rc/Arc) #[fory(id = 0, ref = true)] @@ -174,7 +174,7 @@ struct Container { Controls how integer fields are encoded: ```rust -#[derive(Fory)] +#[derive(ForyObject)] struct Metrics { // Variable-length encoding (smaller for small values) #[fory(id = 0, encoding = "varint")] @@ -208,7 +208,7 @@ struct Metrics { A convenience shorthand for controlling integer encoding: ```rust -#[derive(Fory)] +#[derive(ForyObject)] struct Data { // compress = true -> varint encoding (default) #[fory(id = 0, compress)] @@ -245,10 +245,10 @@ Fory classifies field types to determine default behavior: ## Complete Example ```rust -use fory::Fory; +use fory::ForyObject; use std::rc::Rc; -#[derive(Fory, Default)] +#[derive(ForyObject, Default)] struct Document { // Required fields with tag IDs #[fory(id = 0)] @@ -307,7 +307,7 @@ Invalid configurations are caught at compile time: ```rust // Error: duplicate field IDs -#[derive(Fory)] +#[derive(ForyObject)] struct Bad { #[fory(id = 0)] field1: String, @@ -317,14 +317,14 @@ struct Bad { } // Error: invalid id value -#[derive(Fory)] +#[derive(ForyObject)] struct Bad2 { #[fory(id = -2)] // Compile error: id must be >= -1 field: String, } // Error: conflicting encoding attributes -#[derive(Fory)] +#[derive(ForyObject)] struct Bad3 { #[fory(compress = true, encoding = "fixed")] // Compile error: conflict field: i32, @@ -336,7 +336,7 @@ struct Bad3 { When serializing data to be read by other languages (Java, C++, Go, Python), use field configuration to match encoding expectations: ```rust -#[derive(Fory)] +#[derive(ForyObject)] struct CrossLangData { // Matches Java Integer with varint #[fory(id = 0, encoding = "varint")] @@ -362,7 +362,7 @@ Compatible mode supports schema evolution. It is recommended to configure field ```rust // Version 1 -#[derive(Fory)] +#[derive(ForyObject)] struct DataV1 { #[fory(id = 0)] id: i64, @@ -372,7 +372,7 @@ struct DataV1 { } // Version 2: Added new field -#[derive(Fory)] +#[derive(ForyObject)] struct DataV2 { #[fory(id = 0)] id: i64, @@ -390,7 +390,7 @@ Data serialized with V1 can be deserialized with V2 (new field will be `None`). Alternatively, field IDs can be omitted (field names will be used in metadata with larger overhead): ```rust -#[derive(Fory)] +#[derive(ForyObject)] struct Data { id: i64, name: String, @@ -411,7 +411,7 @@ You **need to configure fields** when: ```rust // Xlang mode: explicit configuration required -#[derive(Fory)] +#[derive(ForyObject)] struct User { #[fory(id = 0)] name: String, // Non-nullable by default diff --git a/docs/guide/xlang/field-nullability.md b/docs/guide/xlang/field-nullability.md index 46e3432e86..5bd3494e00 100644 --- a/docs/guide/xlang/field-nullability.md +++ b/docs/guide/xlang/field-nullability.md @@ -137,10 +137,9 @@ fory.register_type(Person, typename="example.Person") ### Rust ```rust -use fory::Fory; +use fory::{Fory, ForyObject}; -#[derive(Fory)] -#[tag("example.Person")] +#[derive(ForyObject)] struct Person { // Non-nullable by default name: String, @@ -167,8 +166,8 @@ type Person struct { Bio *string // Can be nil } -fory := forygo.NewFory() -fory.RegisterTagType("example.Person", Person{}) +fory := forygo.NewFory(forygo.WithXlang(true)) +fory.RegisterNamedStruct(Person{}, "example.Person") ``` ### C++ diff --git a/docs/guide/xlang/field-reference-tracking.md b/docs/guide/xlang/field-reference-tracking.md index e00d45abd1..f6076c13c7 100644 --- a/docs/guide/xlang/field-reference-tracking.md +++ b/docs/guide/xlang/field-reference-tracking.md @@ -49,23 +49,24 @@ fory = pyfory.Fory(xlang=True, ref=True) ### Go ```go -fory := forygo.NewFory(true) // true enables ref tracking +fory := forygo.NewFory( + forygo.WithXlang(true), + forygo.WithTrackRef(true), +) ``` ### C++ ```cpp -auto fory = fory::Fory::create(fory::Config{ - .track_ref = true -}); +auto fory = fory::Fory::builder().xlang(true).track_ref(true).build(); ``` ### Rust ```rust -let fory = Fory::builder() - .with_ref_tracking(true) - .build(); +let fory = Fory::default() + .xlang(true) + .track_ref(true); ``` ## Wire Format @@ -162,8 +163,10 @@ To disable reference tracking for C++ entirely, set #### Rust: Field Attributes ```rust -#[derive(Fory)] -#[tag("example.Document")] +use fory::ForyObject; +use std::rc::Rc; + +#[derive(ForyObject)] struct Document { title: String, @@ -171,7 +174,7 @@ struct Document { author: Rc<Author>, // Explicitly enable ref tracking - #[track_ref] + #[fory(ref = true)] tags: Vec<Tag>, } ``` diff --git a/docs/guide/xlang/getting-started.md b/docs/guide/xlang/getting-started.md index f8bf4a744b..083eb75786 100644 --- a/docs/guide/xlang/getting-started.md +++ b/docs/guide/xlang/getting-started.md @@ -91,11 +91,11 @@ Fory fory = Fory.builder() ```python import pyfory -# xlang mode is enabled by default -fory = pyfory.Fory() +# Cross-language mode must be enabled explicitly +fory = pyfory.Fory(xlang=True) -# Explicit configuration -fory = pyfory.Fory(ref=True) +# Enable reference tracking when needed +fory = pyfory.Fory(xlang=True, ref=True) ``` ### Go @@ -103,9 +103,9 @@ fory = pyfory.Fory(ref=True) ```go import forygo "github.com/apache/fory/go/fory" -fory := forygo.NewFory() +fory := forygo.NewFory(forygo.WithXlang(true)) // Or with reference tracking -fory := forygo.NewFory(true) +fory := forygo.NewFory(forygo.WithXlang(true), forygo.WithTrackRef(true)) ``` ### Rust @@ -113,7 +113,7 @@ fory := forygo.NewFory(true) ```rust use fory::Fory; -let fory = Fory::default(); +let fory = Fory::default().xlang(true); ``` ### JavaScript @@ -159,18 +159,24 @@ fory.register_type(Person, typename="example.Person") **Go:** ```go -fory.RegisterNamedType(Person{}, "example.Person") +fory.RegisterNamedStruct(Person{}, "example.Person") ``` **Rust:** ```rust -#[derive(Fory)] -#[tag("example.Person")] +use fory::{Fory, ForyObject}; + +#[derive(ForyObject)] struct Person { name: String, age: i32, } + +let mut fory = Fory::default().xlang(true); +fory + .register_by_namespace::<Person>("example", "Person") + .expect("register Person"); ``` **JavaScript:** @@ -210,7 +216,7 @@ fory.register_type(Person, type_id=100) **Go:** ```go -fory.Register(Person{}, 100) +fory.RegisterStruct(Person{}, 100) ``` **C++:** @@ -266,7 +272,7 @@ class Person: name: str age: pyfory.Int32Type -fory = pyfory.Fory() +fory = pyfory.Fory(xlang=True) fory.register_type(Person, typename="example.Person") with open("person.bin", "rb") as f: diff --git a/docs/guide/xlang/index.md b/docs/guide/xlang/index.md index bfe051fe30..44a9f3df3d 100644 --- a/docs/guide/xlang/index.md +++ b/docs/guide/xlang/index.md @@ -19,11 +19,11 @@ license: | limitations under the License. --- -Apache Fory™ xlang (cross-language) serialization enables seamless data exchange between different programming languages. Serialize data in one language and deserialize it in another—without IDL definitions, schema compilation, or manual data conversion. +Apache Fory™ xlang (cross-language) serialization enables seamless data exchange between different programming languages. Serialize data in one language and deserialize it in another without manual data conversion. You can use either direct native types (no IDL) or a schema-first Fory IDL workflow. ## Features -- **No IDL Required**: Serialize any object automatically without Protocol Buffers, Thrift, or other IDL definitions +- **No IDL Required**: Serialize objects directly with native language types - **Multi-Language Support**: Java, Python, C++, Go, Rust, JavaScript all interoperate seamlessly - **Reference Support**: Shared and circular references work across language boundaries - **Schema Evolution**: Forward/backward compatibility when class definitions change @@ -91,7 +91,7 @@ class Person: name: str age: pyfory.Int32Type -fory = pyfory.Fory() +fory = pyfory.Fory(xlang=True) fory.register_type(Person, typename="example.Person") # Receive bytes from Java @@ -99,6 +99,43 @@ person = fory.deserialize(bytes_from_java) print(f"{person.name}, {person.age}") # Alice, 30 ``` +## Fory IDL + +For schema-first projects, Fory also provides **Fory IDL** and code generation. + +- Compiler docs: [Fory IDL Overview](../../compiler/index.md) +- Best for large multi-language message contracts and long-lived schemas + +### Minimal IDL Example + +Create `person.fdl`: + +```protobuf +package example; + +message Person { + string name = 1; + int32 age = 2; + optional string email = 3; +} +``` + +Generate code: + +```bash +foryc person.fdl --lang java,python,go,rust,cpp --output ./generated +``` + +This generates native language types with consistent field/type mappings across all targets. + +## When to Fory IDL + +| Option | Use When | Why | +| ---------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| Native xlang types (no IDL) | You only have a few message types and want to move quickly | Avoids the integration/setup cost of introducing and operating the compiler | +| Fory IDL (schema-first + codegen) | You have many messages across multiple languages/teams/services | Provides a single contract, stronger consistency, and easier long-term evolution | +| Hybrid (start native, move to IDL) | Project starts small but message count and cross-team dependency grows | Lets you keep early velocity, then standardize once schema complexity increases | + ## Documentation | Topic | Description | diff --git a/docs/guide/xlang/serialization.md b/docs/guide/xlang/serialization.md index 791f3c363f..c9b270ebd6 100644 --- a/docs/guide/xlang/serialization.md +++ b/docs/guide/xlang/serialization.md @@ -57,7 +57,7 @@ public class Example1 { import pyfory import numpy as np -fory = pyfory.Fory() +fory = pyfory.Fory(xlang=True) object_list = [True, False, "str", -1.1, 1, np.full(100, 0, dtype=np.int32), np.full(20, 0.0, dtype=np.double)] data = fory.serialize(object_list) @@ -80,7 +80,7 @@ import "fmt" func main() { list := []any{true, false, "str", -1.1, 1, make([]int32, 10), make([]float64, 20)} - fory := forygo.NewFory() + fory := forygo.NewFory(forygo.WithXlang(true)) bytes, err := fory.Marshal(list) if err != nil { panic(err) @@ -130,12 +130,12 @@ console.log(result); ### Rust ```rust -use fory::{from_buffer, to_buffer, Fory}; -use std::collections::HashMap; +use fory::Fory; fn run() { - let bin: Vec<u8> = to_buffer(&"hello".to_string()); - let obj: String = from_buffer(&bin).expect("should success"); + let fory = Fory::default().xlang(true); + let bin = fory.serialize(&"hello".to_string()).expect("serialize success"); + let obj: String = fory.deserialize(&bin).expect("deserialize success"); assert_eq!("hello".to_string(), obj); } ``` @@ -238,7 +238,7 @@ class SomeClass2: if __name__ == "__main__": - f = pyfory.Fory() + f = pyfory.Fory(xlang=True) f.register_type(SomeClass1, typename="example.SomeClass1") f.register_type(SomeClass2, typename="example.SomeClass2") obj1 = SomeClass1(f1=True, f2={-1: 2}) @@ -271,6 +271,11 @@ import "fmt" func main() { type SomeClass1 struct { + F1 any + F2 map[int8]int32 + } + + type SomeClass2 struct { F1 any F2 string F3 []any @@ -282,44 +287,37 @@ func main() { F9 float32 F10 float64 F11 []int16 - F12 fory.Int16Slice + F12 []int16 } - - type SomeClass2 struct { - F1 any - F2 map[int8]int32 - } - fory := forygo.NewFory() - if err := fory.RegisterTagType("example.SomeClass1", SomeClass1{}); err != nil { + serializer := forygo.NewFory(forygo.WithXlang(true)) + if err := serializer.RegisterNamedStruct(SomeClass1{}, "example.SomeClass1"); err != nil { panic(err) } - if err := fory.RegisterTagType("example.SomeClass2", SomeClass2{}); err != nil { + if err := serializer.RegisterNamedStruct(SomeClass2{}, "example.SomeClass2"); err != nil { panic(err) } - obj1 := &SomeClass1{} - obj1.F1 = true - obj1.F2 = map[int8]int32{-1: 2} - obj := &SomeClass1{} - obj.F1 = obj1 - obj.F2 = "abc" - obj.F3 = []any{"abc", "abc"} - f4 := map[int8]int32{1: 2} - obj.F4 = f4 - obj.F5 = fory.MaxInt8 - obj.F6 = fory.MaxInt16 - obj.F7 = fory.MaxInt32 - obj.F8 = fory.MaxInt64 - obj.F9 = 1.0 / 2 - obj.F10 = 1 / 3.0 - obj.F11 = []int16{1, 2} - obj.F12 = []int16{-1, 4} - bytes, err := fory.Marshal(obj); + obj1 := &SomeClass1{F1: true, F2: map[int8]int32{-1: 2}} + obj := &SomeClass2{ + F1: obj1, + F2: "abc", + F3: []any{"abc", "abc"}, + F4: map[int8]int32{1: 2}, + F5: 127, + F6: 32767, + F7: 2147483647, + F8: 9223372036854775807, + F9: 1.0 / 2, + F10: 1.0 / 3.0, + F11: []int16{1, 2}, + F12: []int16{-1, 4}, + } + bytes, err := serializer.Marshal(obj) if err != nil { panic(err) } var newValue any // bytes can be deserialized by other languages - if err := fory.Unmarshal(bytes, &newValue); err != nil { + if err := serializer.Unmarshal(bytes, &newValue); err != nil { panic(err) } fmt.Println(newValue) @@ -354,19 +352,17 @@ console.log(result); ```rust use chrono::{NaiveDate, NaiveDateTime}; -use fory::{from_buffer, to_buffer, Fory}; +use fory::{Fory, ForyObject}; use std::collections::HashMap; #[test] fn complex_struct() { - #[derive(Fory, Debug, PartialEq)] - #[tag("example.foo2")] + #[derive(ForyObject, Debug, PartialEq)] struct Animal { category: String, } - #[derive(Fory, Debug, PartialEq)] - #[tag("example.foo")] + #[derive(ForyObject, Debug, PartialEq)] struct Person { c1: Vec<u8>, // binary c2: Vec<i16>, // primitive array @@ -403,8 +399,15 @@ fn complex_struct() { c6: 4.0, }; - let bin: Vec<u8> = to_buffer(&person); - let obj: Person = from_buffer(&bin).expect("should success"); + let mut fory = Fory::default().xlang(true); + fory + .register_by_namespace::<Animal>("example", "foo2") + .expect("register Animal"); + fory + .register_by_namespace::<Person>("example", "foo") + .expect("register Person"); + let bin = fory.serialize(&person).expect("serialize success"); + let obj: Person = fory.deserialize(&bin).expect("deserialize success"); assert_eq!(person, obj); } ``` @@ -458,7 +461,7 @@ class SomeClass: f2: Dict[str, str] f3: Dict[str, str] -fory = pyfory.Fory(ref=True) +fory = pyfory.Fory(xlang=True, ref=True) fory.register_type(SomeClass, typename="example.SomeClass") obj = SomeClass() obj.f2 = {"k1": "v1", "k2": "v2"} @@ -482,8 +485,11 @@ func main() { F2 map[string]string F3 map[string]string } - fory := forygo.NewFory(true) - if err := fory.Register(SomeClass{}, 65); err != nil { + fory := forygo.NewFory( + forygo.WithXlang(true), + forygo.WithTrackRef(true), + ) + if err := fory.RegisterStruct(SomeClass{}, 65); err != nil { panic(err) } value := &SomeClass{F2: map[string]string{"k1": "v1", "k2": "v2"}} diff --git a/docs/guide/xlang/troubleshooting.md b/docs/guide/xlang/troubleshooting.md index 5c0e59a167..09def125bf 100644 --- a/docs/guide/xlang/troubleshooting.md +++ b/docs/guide/xlang/troubleshooting.md @@ -187,7 +187,7 @@ Fory fory = Fory.builder() ```python # Python -fory = pyfory.Fory(ref=True) +fory = pyfory.Fory(xlang=True, ref=True) ``` ### Duplicate Objects diff --git a/docs/guide/xlang/zero-copy.md b/docs/guide/xlang/zero-copy.md index 8c0001494d..e1ad25fa28 100644 --- a/docs/guide/xlang/zero-copy.md +++ b/docs/guide/xlang/zero-copy.md @@ -84,7 +84,7 @@ import array import pyfory import numpy as np -fory = pyfory.Fory() +fory = pyfory.Fory(xlang=True) # Data with large arrays data = [ @@ -115,7 +115,7 @@ import forygo "github.com/apache/fory/go/fory" import "fmt" func main() { - fory := forygo.NewFory() + serializer := forygo.NewFory(forygo.WithXlang(true)) // Data with large arrays list := []any{ @@ -123,24 +123,26 @@ func main() { make([]byte, 1000), // Large byte array } - buf := fory.NewByteBuffer(nil) - var bufferObjects []fory.BufferObject + buf := forygo.NewByteBuffer(nil) + var bufferObjects []forygo.BufferObject // Collect buffer objects during serialization - fory.Serialize(buf, list, func(o fory.BufferObject) bool { + if err := serializer.SerializeWithCallback(buf, list, func(o forygo.BufferObject) bool { bufferObjects = append(bufferObjects, o) return false - }) + }); err != nil { + panic(err) + } // Convert to buffers for transport - var buffers []*fory.ByteBuffer + var buffers []*forygo.ByteBuffer for _, o := range bufferObjects { buffers = append(buffers, o.ToBuffer()) } // Deserialize with buffers var newList []any - if err := fory.Deserialize(buf, &newList, buffers); err != nil { + if err := serializer.DeserializeWithCallbackBuffers(buf, &newList, buffers); err != nil { panic(err) } fmt.Println(newList) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
