This is an automated email from the ASF dual-hosted git repository.

wangweipeng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fury.git


The following commit(s) were added to refs/heads/main by this push:
     new fb34adf6 feat(Rust): Refine Code Structure &  Prepare for Future 
Compatibility Features (#1787)
fb34adf6 is described below

commit fb34adf6e312e62224e1484b528b319ec5e30629
Author: weipeng <[email protected]>
AuthorDate: Sat Aug 3 07:07:11 2024 +0800

    feat(Rust): Refine Code Structure &  Prepare for Future Compatibility 
Features (#1787)
---
 rust/Cargo.toml                                    |   1 +
 rust/{fury => fury-core}/Cargo.toml                |   3 +-
 rust/{fury => fury-core}/benches/simd_bench.rs     |   0
 rust/{fury => fury-core}/src/buffer.rs             |   0
 rust/{fury => fury-core}/src/error.rs              |  25 +-
 rust/fury-core/src/fury.rs                         |  60 ++++
 .../bit_util.rs => fury-core/src/internal/bool.rs} |  25 +-
 rust/fury-core/src/internal/datetime.rs            |  80 +++++
 rust/fury-core/src/internal/list.rs                |  60 ++++
 rust/fury-core/src/internal/map.rs                 |  66 ++++
 .../src/meta => fury-core/src/internal}/mod.rs     |  12 +-
 rust/fury-core/src/internal/number.rs              |  65 ++++
 rust/fury-core/src/internal/option.rs              |  87 +++++
 rust/fury-core/src/internal/primitive_list.rs      |  91 +++++
 rust/fury-core/src/internal/set.rs                 |  61 ++++
 .../lib.rs => fury-core/src/internal/string.rs}    |  47 +--
 .../src/row/bit_util.rs => fury-core/src/lib.rs}   |  16 +-
 rust/fury-core/src/meta/meta_store.rs              |  80 +++++
 rust/{fury => fury-core}/src/meta/meta_string.rs   |  25 +-
 rust/{fury => fury-core}/src/meta/mod.rs           |   7 +-
 rust/{fury => fury-core}/src/meta/string_util.rs   |   6 +-
 rust/fury-core/src/meta/type_meta.rs               | 113 +++++++
 rust/fury-core/src/read_state.rs                   |  66 ++++
 rust/{fury => fury-core}/src/row/bit_util.rs       |   0
 rust/{fury => fury-core}/src/row/mod.rs            |   0
 rust/{fury => fury-core}/src/row/reader.rs         |   0
 rust/{fury => fury-core}/src/row/row.rs            |   2 +-
 rust/{fury => fury-core}/src/row/writer.rs         |   0
 rust/fury-core/src/serializer.rs                   |  86 +++++
 rust/{fury => fury-core}/src/types.rs              | 134 +-------
 rust/{fury => fury-core}/src/util.rs               |   0
 rust/fury-core/src/write_state.rs                  |  82 +++++
 rust/{fury => fury-core}/tests/de.rs               |   0
 rust/fury-derive/Cargo.toml                        |   1 +
 rust/fury-derive/src/fury_meta.rs                  | 139 ++++----
 rust/fury-derive/src/fury_row.rs                   |  16 +-
 rust/fury-derive/src/lib.rs                        |   9 +-
 rust/fury/Cargo.toml                               |  28 +-
 rust/fury/src/deserializer.rs                      | 269 ---------------
 rust/fury/src/lib.rs                               |  26 +-
 rust/fury/src/serializer.rs                        | 365 ---------------------
 rust/tests/Cargo.toml                              |   2 +-
 rust/tests/tests/test_complex_struct.rs            |  56 +---
 rust/tests/tests/test_meta_string.rs               |   2 +-
 rust/tests/tests/test_row.rs                       |   3 +-
 rust/tests/tests/test_util.rs                      |   2 +-
 46 files changed, 1209 insertions(+), 1009 deletions(-)

diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 1e63c51a..93a4528b 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -17,6 +17,7 @@
 
 [workspace]
 members = [
+    "fury-core",
     "fury",
     "fury-derive",
     "tests"
diff --git a/rust/fury/Cargo.toml b/rust/fury-core/Cargo.toml
similarity index 94%
copy from rust/fury/Cargo.toml
copy to rust/fury-core/Cargo.toml
index bba04afb..3be240ff 100644
--- a/rust/fury/Cargo.toml
+++ b/rust/fury-core/Cargo.toml
@@ -16,7 +16,7 @@
 # under the License.
 
 [package]
-name = "fury"
+name = "fury-core"
 version.workspace = true
 edition.workspace = true
 rust-version.workspace = true
@@ -25,7 +25,6 @@ rust-version.workspace = true
 proc-macro2 = { default-features = false, version = "1.0" }
 syn = { default-features = false, version = "2.0", features = ["full", "fold"] 
}
 quote = { default-features = false, version = "1.0" }
-fury-derive = { path = "../fury-derive" }
 lazy_static = { version = "1.4" }
 byteorder = { version = "1.4" }
 chrono = "0.4"
diff --git a/rust/fury/benches/simd_bench.rs 
b/rust/fury-core/benches/simd_bench.rs
similarity index 100%
rename from rust/fury/benches/simd_bench.rs
rename to rust/fury-core/benches/simd_bench.rs
diff --git a/rust/fury/src/buffer.rs b/rust/fury-core/src/buffer.rs
similarity index 100%
rename from rust/fury/src/buffer.rs
rename to rust/fury-core/src/buffer.rs
diff --git a/rust/fury/src/error.rs b/rust/fury-core/src/error.rs
similarity index 66%
rename from rust/fury/src/error.rs
rename to rust/fury-core/src/error.rs
index 73cc9105..717d18bf 100644
--- a/rust/fury/src/error.rs
+++ b/rust/fury-core/src/error.rs
@@ -47,8 +47,29 @@ pub enum Error {
     TagType(u8),
 
     #[error("Only Xlang supported; receive: {language:?}")]
-    UnsupportLanguage { language: Language },
+    UnsupportedLanguage { language: Language },
 
     #[error("Unsupported Language Code; receive: {code:?}")]
-    UnsupportLanguageCode { code: u8 },
+    UnsupportedLanguageCode { code: u8 },
+
+    #[error("encoded_data cannot be empty")]
+    EncodedDataEmpty,
+
+    #[error("Long meta string than 32767 is not allowed")]
+    LengthExceed,
+
+    #[error("Non-ASCII characters in meta string are not allowed")]
+    OnlyAllowASCII,
+
+    #[error("Unsupported character for LOWER_SPECIAL encoding: {ch:?}")]
+    UnsupportedLowerSpecialCharacter { ch: char },
+
+    #[error("Unsupported character for LOWER_UPPER_DIGIT_SPECIAL encoding: 
{ch:?}")]
+    UnsupportedLowerUpperDigitSpecialCharacter { ch: char },
+
+    #[error("Invalid character value for LOWER_SPECIAL decoding: {value:?}")]
+    InvalidLowerSpecialValue { value: u8 },
+
+    #[error("Invalid character value for LOWER_UPPER_DIGIT_SPECIAL decoding: 
{value:?}")]
+    InvalidLowerUpperDigitSpecialValue { value: u8 },
 }
diff --git a/rust/fury-core/src/fury.rs b/rust/fury-core/src/fury.rs
new file mode 100644
index 00000000..34a1532e
--- /dev/null
+++ b/rust/fury-core/src/fury.rs
@@ -0,0 +1,60 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::buffer::{Reader, Writer};
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::Mode;
+use crate::write_state::WriteState;
+
+pub struct Fury {
+    mode: Mode,
+}
+
+impl Default for Fury {
+    fn default() -> Self {
+        Fury {
+            mode: Mode::Compatible,
+        }
+    }
+}
+
+impl Fury {
+    pub fn mode(&mut self, mode: Mode) {
+        self.mode = mode;
+    }
+
+    pub fn get_mode(&self) -> &Mode {
+        &self.mode
+    }
+
+    pub fn deserialize<T: Serializer>(&self, bf: &[u8]) -> Result<T, Error> {
+        let reader = Reader::new(bf);
+        let mut deserializer = ReadState::new(self, reader);
+        deserializer.head()?;
+        <T as Serializer>::deserialize(&mut deserializer)
+    }
+
+    pub fn serialize<T: Serializer>(&self, record: &T) -> Vec<u8> {
+        let mut writer = Writer::default();
+        let mut serializer = WriteState::new(self, &mut writer);
+        serializer.head::<T>();
+        <T as Serializer>::serialize(record, &mut serializer);
+        writer.dump()
+    }
+}
diff --git a/rust/fury/src/row/bit_util.rs b/rust/fury-core/src/internal/bool.rs
similarity index 58%
copy from rust/fury/src/row/bit_util.rs
copy to rust/fury-core/src/internal/bool.rs
index bbb94e5f..edeebbd8 100644
--- a/rust/fury/src/row/bit_util.rs
+++ b/rust/fury-core/src/internal/bool.rs
@@ -15,8 +15,27 @@
 // specific language governing permissions and limitations
 // under the License.
 
-const WORD_SIZE: usize = 8;
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::FieldType;
+use crate::write_state::WriteState;
+use std::mem;
 
-pub fn calculate_bitmap_width_in_bytes(num_fields: usize) -> usize {
-    ((num_fields + 63) / 64) * WORD_SIZE
+impl Serializer for bool {
+    fn reserved_space() -> usize {
+        mem::size_of::<i32>()
+    }
+
+    fn write(&self, serializer: &mut WriteState) {
+        serializer.writer.u8(if *self { 1 } else { 0 });
+    }
+
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        Ok(deserializer.reader.u8() == 1)
+    }
+
+    fn ty() -> FieldType {
+        FieldType::BOOL
+    }
 }
diff --git a/rust/fury-core/src/internal/datetime.rs 
b/rust/fury-core/src/internal/datetime.rs
new file mode 100644
index 00000000..8852a077
--- /dev/null
+++ b/rust/fury-core/src/internal/datetime.rs
@@ -0,0 +1,80 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::{FieldType, FuryGeneralList};
+use crate::write_state::WriteState;
+use chrono::{DateTime, Days, NaiveDate, NaiveDateTime};
+use std::mem;
+
+impl Serializer for NaiveDateTime {
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        let timestamp = deserializer.reader.u64();
+        let ret = DateTime::from_timestamp_millis(timestamp as i64).map(|dt| 
dt.naive_utc());
+        match ret {
+            Some(r) => Ok(r),
+            None => Err(Error::NaiveDateTime),
+        }
+    }
+
+    fn write(&self, serializer: &mut WriteState) {
+        serializer
+            .writer
+            .u64(self.and_utc().timestamp_millis() as u64);
+    }
+
+    fn reserved_space() -> usize {
+        mem::size_of::<u64>()
+    }
+
+    fn ty() -> FieldType {
+        FieldType::TIMESTAMP
+    }
+}
+
+impl FuryGeneralList for NaiveDateTime {}
+
+lazy_static::lazy_static!(
+    static ref EPOCH: NaiveDate = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
+);
+
+impl Serializer for NaiveDate {
+    fn write(&self, serializer: &mut WriteState) {
+        let days_since_epoch = self.signed_duration_since(*EPOCH).num_days();
+        serializer.writer.u64(days_since_epoch as u64);
+    }
+
+    fn reserved_space() -> usize {
+        mem::size_of::<u64>()
+    }
+
+    fn read(serializer: &mut ReadState) -> Result<Self, Error> {
+        let days = serializer.reader.u64();
+        match EPOCH.checked_add_days(Days::new(days)) {
+            Some(value) => Ok(value),
+            None => Err(Error::NaiveDate),
+        }
+    }
+
+    fn ty() -> FieldType {
+        FieldType::DATE
+    }
+}
+
+impl FuryGeneralList for NaiveDate {}
diff --git a/rust/fury-core/src/internal/list.rs 
b/rust/fury-core/src/internal/list.rs
new file mode 100644
index 00000000..491e377b
--- /dev/null
+++ b/rust/fury-core/src/internal/list.rs
@@ -0,0 +1,60 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::{FieldType, FuryGeneralList, SIZE_OF_REF_AND_TYPE};
+use crate::write_state::WriteState;
+use std::mem;
+
+impl<T> Serializer for Vec<T>
+where
+    T: Serializer + FuryGeneralList,
+{
+    fn write(&self, serializer: &mut WriteState) {
+        serializer.writer.var_int32(self.len() as i32);
+        serializer
+            .writer
+            .reserve((<Self as Serializer>::reserved_space() + 
SIZE_OF_REF_AND_TYPE) * self.len());
+        for item in self.iter() {
+            item.serialize(serializer);
+        }
+    }
+
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        // length
+        let len = deserializer.reader.var_int32();
+        // value
+        let mut result = Vec::new();
+        for _ in 0..len {
+            result.push(T::deserialize(deserializer)?);
+        }
+        Ok(result)
+    }
+
+    fn reserved_space() -> usize {
+        // size of the vec
+        mem::size_of::<u32>()
+    }
+
+    fn ty() -> FieldType {
+        FieldType::ARRAY
+    }
+}
+
+impl<T> FuryGeneralList for Vec<T> where T: Serializer {}
diff --git a/rust/fury-core/src/internal/map.rs 
b/rust/fury-core/src/internal/map.rs
new file mode 100644
index 00000000..791da121
--- /dev/null
+++ b/rust/fury-core/src/internal/map.rs
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::{FieldType, FuryGeneralList, SIZE_OF_REF_AND_TYPE};
+use crate::write_state::WriteState;
+use std::collections::HashMap;
+use std::mem;
+
+impl<T1: Serializer + Eq + std::hash::Hash, T2: Serializer> Serializer for 
HashMap<T1, T2> {
+    fn write(&self, serializer: &mut WriteState) {
+        // length
+        serializer.writer.var_int32(self.len() as i32);
+
+        let reserved_space = (<T1 as Serializer>::reserved_space() + 
SIZE_OF_REF_AND_TYPE)
+            * self.len()
+            + (<T2 as Serializer>::reserved_space() + SIZE_OF_REF_AND_TYPE) * 
self.len();
+        serializer.writer.reserve(reserved_space);
+
+        // key-value
+        for i in self.iter() {
+            i.0.serialize(serializer);
+            i.1.serialize(serializer);
+        }
+    }
+
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        // length
+        let len = deserializer.reader.var_int32();
+        let mut result = HashMap::new();
+        // key-value
+        for _ in 0..len {
+            result.insert(
+                <T1 as Serializer>::deserialize(deserializer)?,
+                <T2 as Serializer>::deserialize(deserializer)?,
+            );
+        }
+        Ok(result)
+    }
+
+    fn reserved_space() -> usize {
+        mem::size_of::<i32>()
+    }
+
+    fn ty() -> FieldType {
+        FieldType::MAP
+    }
+}
+
+impl<T1: Serializer + Eq + std::hash::Hash, T2: Serializer> FuryGeneralList 
for HashMap<T1, T2> {}
diff --git a/rust/fury/src/meta/mod.rs b/rust/fury-core/src/internal/mod.rs
similarity index 88%
copy from rust/fury/src/meta/mod.rs
copy to rust/fury-core/src/internal/mod.rs
index 02871e82..4b4db5d5 100644
--- a/rust/fury/src/meta/mod.rs
+++ b/rust/fury-core/src/internal/mod.rs
@@ -15,6 +15,12 @@
 // specific language governing permissions and limitations
 // under the License.
 
-mod meta_string;
-mod string_util;
-pub use meta_string::{Encoding, MetaStringDecoder, MetaStringEncoder};
+mod bool;
+mod datetime;
+mod list;
+mod map;
+mod number;
+mod option;
+mod primitive_list;
+mod set;
+mod string;
diff --git a/rust/fury-core/src/internal/number.rs 
b/rust/fury-core/src/internal/number.rs
new file mode 100644
index 00000000..ef4f5083
--- /dev/null
+++ b/rust/fury-core/src/internal/number.rs
@@ -0,0 +1,65 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::{FieldType, FuryGeneralList};
+use crate::write_state::WriteState;
+
+#[allow(dead_code)]
+fn to_u8_slice<T>(slice: &[T]) -> &[u8] {
+    let byte_len = std::mem::size_of_val(slice);
+    unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::<u8>(), byte_len) 
}
+}
+
+macro_rules! impl_num_serializer {
+    ($name: ident, $ty:tt, $field_type: expr) => {
+        impl Serializer for $ty {
+            fn write(&self, serializer: &mut WriteState) {
+                serializer.writer.$name(*self);
+            }
+
+            fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+                Ok(deserializer.reader.$name())
+            }
+
+            fn reserved_space() -> usize {
+                std::mem::size_of::<$ty>()
+            }
+
+            fn ty() -> FieldType {
+                $field_type
+            }
+        }
+    };
+}
+impl FuryGeneralList for i8 {}
+impl FuryGeneralList for u16 {}
+impl FuryGeneralList for u32 {}
+impl FuryGeneralList for u64 {}
+
+impl_num_serializer!(i8, i8, FieldType::INT8);
+impl_num_serializer!(u8, u8, FieldType::UINT8);
+impl_num_serializer!(i16, i16, FieldType::INT16);
+impl_num_serializer!(u16, u16, FieldType::UINT16);
+impl_num_serializer!(i32, i32, FieldType::INT32);
+impl_num_serializer!(u32, u32, FieldType::UINT32);
+impl_num_serializer!(u64, u64, FieldType::UINT64);
+impl_num_serializer!(i64, i64, FieldType::INT64);
+impl_num_serializer!(f32, f32, FieldType::FLOAT);
+impl_num_serializer!(f64, f64, FieldType::DOUBLE);
diff --git a/rust/fury-core/src/internal/option.rs 
b/rust/fury-core/src/internal/option.rs
new file mode 100644
index 00000000..d4f5b64e
--- /dev/null
+++ b/rust/fury-core/src/internal/option.rs
@@ -0,0 +1,87 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::{FieldType, FuryGeneralList, RefFlag};
+use crate::write_state::WriteState;
+
+impl<T: Serializer> Serializer for Option<T> {
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        Ok(Some(T::read(deserializer)?))
+    }
+
+    fn deserialize(deserializer: &mut ReadState) -> Result<Self, Error> {
+        // ref flag
+        let ref_flag = deserializer.reader.i8();
+
+        if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == 
(RefFlag::RefValue as i8) {
+            // type_id
+            let type_id = deserializer.reader.i16();
+
+            if type_id != T::ty() as i16 {
+                Err(Error::FieldType {
+                    expected: T::ty(),
+                    actial: type_id,
+                })
+            } else {
+                Ok(Some(T::read(deserializer)?))
+            }
+        } else if ref_flag == (RefFlag::Null as i8) {
+            Ok(None)
+        } else if ref_flag == (RefFlag::Ref as i8) {
+            Err(Error::Ref)
+        } else {
+            Err(Error::BadRefFlag)
+        }
+    }
+
+    fn write(&self, serializer: &mut WriteState) {
+        if let Some(v) = self {
+            T::write(v, serializer)
+        } else {
+            unreachable!("write should be call by serialize")
+        }
+    }
+
+    fn serialize(&self, serializer: &mut WriteState) {
+        match self {
+            Some(v) => {
+                // ref flag
+                serializer.writer.i8(RefFlag::NotNullValue as i8);
+                // type
+                serializer.writer.i16(T::ty() as i16);
+
+                v.write(serializer);
+            }
+            None => {
+                serializer.writer.i8(RefFlag::Null as i8);
+            }
+        }
+    }
+
+    fn reserved_space() -> usize {
+        std::mem::size_of::<T>()
+    }
+
+    fn ty() -> FieldType {
+        T::ty()
+    }
+}
+
+impl<T: Serializer> FuryGeneralList for Option<T> {}
diff --git a/rust/fury-core/src/internal/primitive_list.rs 
b/rust/fury-core/src/internal/primitive_list.rs
new file mode 100644
index 00000000..f8ab7c3a
--- /dev/null
+++ b/rust/fury-core/src/internal/primitive_list.rs
@@ -0,0 +1,91 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::FieldType;
+use crate::write_state::WriteState;
+use std::mem;
+
+pub fn to_u8_slice<T>(slice: &[T]) -> &[u8] {
+    let byte_len = std::mem::size_of_val(slice);
+    unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::<u8>(), byte_len) 
}
+}
+
+fn from_u8_slice<T: Clone>(slice: &[u8]) -> Vec<T> {
+    let byte_len = slice.len() / mem::size_of::<T>();
+    unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::<T>(), byte_len) 
}.to_vec()
+}
+
+macro_rules! impl_primitive_vec {
+    ($name: ident, $ty:tt, $field_type: expr) => {
+        impl Serializer for Vec<$ty> {
+            fn write(&self, serializer: &mut WriteState) {
+                serializer.writer.var_int32(self.len() as i32);
+                serializer
+                    .writer
+                    .reserve(self.len() * mem::size_of::<$ty>());
+                serializer.writer.bytes(to_u8_slice(self));
+            }
+
+            fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+                // length
+                let len = (deserializer.reader.var_int32() as usize) * 
mem::size_of::<$ty>();
+                Ok(from_u8_slice::<$ty>(
+                    deserializer.reader.bytes(len as usize),
+                ))
+            }
+
+            fn reserved_space() -> usize {
+                mem::size_of::<i32>()
+            }
+
+            fn ty() -> FieldType {
+                $field_type
+            }
+        }
+    };
+}
+
+impl Serializer for Vec<bool> {
+    fn write(&self, serializer: &mut WriteState) {
+        serializer.writer.var_int32(self.len() as i32);
+        serializer.writer.bytes(to_u8_slice(self));
+    }
+
+    fn reserved_space() -> usize {
+        mem::size_of::<u8>()
+    }
+
+    fn ty() -> FieldType {
+        FieldType::FuryPrimitiveBoolArray
+    }
+
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        let size = deserializer.reader.var_int32();
+        let bytes = deserializer.reader.bytes(size as usize).to_vec();
+        Ok(unsafe { mem::transmute::<Vec<u8>, Vec<bool>>(bytes) })
+    }
+}
+
+impl_primitive_vec!(u8, u8, FieldType::BINARY);
+impl_primitive_vec!(i16, i16, FieldType::FuryPrimitiveShortArray);
+impl_primitive_vec!(i32, i32, FieldType::FuryPrimitiveIntArray);
+impl_primitive_vec!(i64, i64, FieldType::FuryPrimitiveLongArray);
+impl_primitive_vec!(f32, f32, FieldType::FuryPrimitiveFloatArray);
+impl_primitive_vec!(f64, f64, FieldType::FuryPrimitiveDoubleArray);
diff --git a/rust/fury-core/src/internal/set.rs 
b/rust/fury-core/src/internal/set.rs
new file mode 100644
index 00000000..8989e6a2
--- /dev/null
+++ b/rust/fury-core/src/internal/set.rs
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::{FieldType, FuryGeneralList, SIZE_OF_REF_AND_TYPE};
+use crate::write_state::WriteState;
+use std::collections::HashSet;
+use std::mem;
+
+impl<T: Serializer + Eq + std::hash::Hash> Serializer for HashSet<T> {
+    fn write(&self, serializer: &mut WriteState) {
+        // length
+        serializer.writer.i32(self.len() as i32);
+
+        let reserved_space =
+            (<T as Serializer>::reserved_space() + SIZE_OF_REF_AND_TYPE) * 
self.len();
+        serializer.writer.reserve(reserved_space);
+
+        // key-value
+        for i in self.iter() {
+            i.serialize(serializer);
+        }
+    }
+
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        // length
+        let len = deserializer.reader.var_int32();
+        let mut result = HashSet::new();
+        // key-value
+        for _ in 0..len {
+            result.insert(<T as Serializer>::deserialize(deserializer)?);
+        }
+        Ok(result)
+    }
+
+    fn reserved_space() -> usize {
+        mem::size_of::<i32>()
+    }
+
+    fn ty() -> FieldType {
+        FieldType::FurySet
+    }
+}
+
+impl<T: Serializer + Eq + std::hash::Hash> FuryGeneralList for HashSet<T> {}
diff --git a/rust/fury/src/lib.rs b/rust/fury-core/src/internal/string.rs
similarity index 52%
copy from rust/fury/src/lib.rs
copy to rust/fury-core/src/internal/string.rs
index 248de27d..fc473b14 100644
--- a/rust/fury/src/lib.rs
+++ b/rust/fury-core/src/internal/string.rs
@@ -15,28 +15,31 @@
 // specific language governing permissions and limitations
 // under the License.
 
-mod buffer;
-mod deserializer;
-mod error;
-mod meta;
-mod row;
-mod serializer;
-mod types;
-mod util;
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::serializer::Serializer;
+use crate::types::{FieldType, FuryGeneralList};
+use crate::write_state::WriteState;
+use std::mem;
 
-pub use deserializer::from_buffer;
-pub use error::Error;
-pub use fury_derive::*;
-pub use meta::{Encoding, MetaStringDecoder, MetaStringEncoder};
-pub use row::{from_row, to_row};
-pub use serializer::to_buffer;
-pub use util::to_utf8;
+impl Serializer for String {
+    fn reserved_space() -> usize {
+        mem::size_of::<i32>()
+    }
 
-pub mod __derive {
-    pub use crate::buffer::{Reader, Writer};
-    pub use crate::deserializer::{Deserialize, DeserializerState};
-    pub use crate::row::{ArrayViewer, ArrayWriter, Row, StructViewer, 
StructWriter};
-    pub use crate::serializer::{Serialize, SerializerState};
-    pub use crate::types::{compute_struct_hash, FieldType, FuryMeta, 
SIZE_OF_REF_AND_TYPE};
-    pub use crate::Error;
+    fn write(&self, serializer: &mut WriteState) {
+        serializer.writer.var_int32(self.len() as i32);
+        serializer.writer.bytes(self.as_bytes());
+    }
+
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error> {
+        let len = deserializer.reader.var_int32();
+        Ok(deserializer.reader.string(len as usize))
+    }
+
+    fn ty() -> FieldType {
+        FieldType::STRING
+    }
 }
+
+impl FuryGeneralList for String {}
diff --git a/rust/fury/src/row/bit_util.rs b/rust/fury-core/src/lib.rs
similarity index 81%
copy from rust/fury/src/row/bit_util.rs
copy to rust/fury-core/src/lib.rs
index bbb94e5f..18e85d97 100644
--- a/rust/fury/src/row/bit_util.rs
+++ b/rust/fury-core/src/lib.rs
@@ -15,8 +15,14 @@
 // specific language governing permissions and limitations
 // under the License.
 
-const WORD_SIZE: usize = 8;
-
-pub fn calculate_bitmap_width_in_bytes(num_fields: usize) -> usize {
-    ((num_fields + 63) / 64) * WORD_SIZE
-}
+pub mod buffer;
+pub mod error;
+pub mod fury;
+pub mod internal;
+pub mod meta;
+pub mod read_state;
+pub mod row;
+pub mod serializer;
+pub mod types;
+pub mod util;
+pub mod write_state;
diff --git a/rust/fury-core/src/meta/meta_store.rs 
b/rust/fury-core/src/meta/meta_store.rs
new file mode 100644
index 00000000..5cc4149d
--- /dev/null
+++ b/rust/fury-core/src/meta/meta_store.rs
@@ -0,0 +1,80 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::buffer::{Reader, Writer};
+use crate::error::Error;
+use crate::meta::TypeMeta;
+use std::collections::HashMap;
+
+#[allow(dead_code)]
+pub struct MetaReaderStore {
+    reading_type_defs: Vec<TypeMeta>,
+}
+
+#[allow(dead_code)]
+impl MetaReaderStore {
+    fn new() -> MetaReaderStore {
+        MetaReaderStore {
+            reading_type_defs: Vec::new(),
+        }
+    }
+
+    fn get(&self, index: usize) -> &TypeMeta {
+        unsafe { self.reading_type_defs.get_unchecked(index) }
+    }
+
+    fn from_bytes(reader: &mut Reader) -> MetaReaderStore {
+        let meta_size = reader.var_int32();
+        let mut reading_type_defs = Vec::<TypeMeta>::with_capacity(meta_size 
as usize);
+        for _ in 0..meta_size {
+            reading_type_defs.push(TypeMeta::from_bytes(reader));
+        }
+        MetaReaderStore { reading_type_defs }
+    }
+}
+
+#[derive(Default)]
+pub struct MetaWriterStore<'a> {
+    writing_type_defs: Vec<&'a [u8]>,
+    index_map: HashMap<u32, usize>,
+}
+
+#[allow(dead_code)]
+impl<'a> MetaWriterStore<'a> {
+    pub fn push<'b: 'a>(&mut self, type_id: u32, type_meta_bytes: &'b [u8]) -> 
usize {
+        match self.index_map.get(&type_id) {
+            None => {
+                let index = self.writing_type_defs.len();
+                self.writing_type_defs.push(type_meta_bytes);
+                self.index_map.insert(type_id, index);
+                index
+            }
+            Some(index) => *index,
+        }
+    }
+
+    fn to_bytes(&self, writer: &mut Writer) -> Result<(), Error> {
+        for item in self.writing_type_defs.iter() {
+            writer.bytes(item)
+        }
+        Ok(())
+    }
+
+    fn reset(&mut self) {
+        self.writing_type_defs.clear();
+    }
+}
diff --git a/rust/fury/src/meta/meta_string.rs 
b/rust/fury-core/src/meta/meta_string.rs
similarity index 94%
rename from rust/fury/src/meta/meta_string.rs
rename to rust/fury-core/src/meta/meta_string.rs
index 627433c9..282b1ab5 100644
--- a/rust/fury/src/meta/meta_string.rs
+++ b/rust/fury-core/src/meta/meta_string.rs
@@ -15,6 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use crate::error::Error;
 use crate::meta::string_util;
 
 #[derive(Debug, PartialEq)]
@@ -26,30 +27,6 @@ pub enum Encoding {
     AllToLowerSpecial = 0x04,
 }
 
-#[derive(thiserror::Error, Debug)]
-pub enum Error {
-    #[error("encoded_data cannot be empty")]
-    EncodedDataEmpty,
-
-    #[error("Long meta string than 32767 is not allowed")]
-    LengthExceed,
-
-    #[error("Non-ASCII characters in meta string are not allowed")]
-    OnlyAllowASCII,
-
-    #[error("Unsupported character for LOWER_SPECIAL encoding: {ch:?}")]
-    UnsupportedLowerSpecialCharacter { ch: char },
-
-    #[error("Unsupported character for LOWER_UPPER_DIGIT_SPECIAL encoding: 
{ch:?}")]
-    UnsupportedLowerUpperDigitSpecialCharacter { ch: char },
-
-    #[error("Invalid character value for LOWER_SPECIAL decoding: {value:?}")]
-    InvalidLowerSpecialValue { value: u8 },
-
-    #[error("Invalid character value for LOWER_UPPER_DIGIT_SPECIAL decoding: 
{value:?}")]
-    InvalidLowerUpperDigitSpecialValue { value: u8 },
-}
-
 #[derive(Debug, PartialEq)]
 pub struct MetaString {
     pub original: String,
diff --git a/rust/fury/src/meta/mod.rs b/rust/fury-core/src/meta/mod.rs
similarity index 79%
rename from rust/fury/src/meta/mod.rs
rename to rust/fury-core/src/meta/mod.rs
index 02871e82..58a81ea0 100644
--- a/rust/fury/src/meta/mod.rs
+++ b/rust/fury-core/src/meta/mod.rs
@@ -15,6 +15,11 @@
 // specific language governing permissions and limitations
 // under the License.
 
+mod meta_store;
 mod meta_string;
 mod string_util;
-pub use meta_string::{Encoding, MetaStringDecoder, MetaStringEncoder};
+mod type_meta;
+
+pub use meta_store::{MetaReaderStore, MetaWriterStore};
+pub use meta_string::{Encoding, MetaString, MetaStringDecoder, 
MetaStringEncoder};
+pub use type_meta::{FieldInfo, TypeMeta};
diff --git a/rust/fury/src/meta/string_util.rs 
b/rust/fury-core/src/meta/string_util.rs
similarity index 97%
rename from rust/fury/src/meta/string_util.rs
rename to rust/fury-core/src/meta/string_util.rs
index ea865911..bd65beff 100644
--- a/rust/fury/src/meta/string_util.rs
+++ b/rust/fury-core/src/meta/string_util.rs
@@ -25,14 +25,14 @@ use std::arch::x86_64::*;
 use std::arch::x86_64::*;
 
 #[cfg(target_arch = "x86_64")]
-pub(crate) const MIN_DIM_SIZE_AVX: usize = 32;
+pub const MIN_DIM_SIZE_AVX: usize = 32;
 
 #[cfg(any(
     target_arch = "x86",
     target_arch = "x86_64",
     all(target_arch = "aarch64", target_feature = "neon")
 ))]
-pub(crate) const MIN_DIM_SIZE_SIMD: usize = 16;
+pub const MIN_DIM_SIZE_SIMD: usize = 16;
 
 #[cfg(target_arch = "x86_64")]
 unsafe fn is_latin_avx(s: &str) -> bool {
@@ -108,7 +108,7 @@ fn is_latin_standard(s: &str) -> bool {
     s.bytes().all(|b| b.is_ascii())
 }
 
-pub(crate) fn is_latin(s: &str) -> bool {
+pub fn is_latin(s: &str) -> bool {
     #[cfg(target_arch = "x86_64")]
     {
         if is_x86_feature_detected!("avx")
diff --git a/rust/fury-core/src/meta/type_meta.rs 
b/rust/fury-core/src/meta/type_meta.rs
new file mode 100644
index 00000000..99ac37bd
--- /dev/null
+++ b/rust/fury-core/src/meta/type_meta.rs
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::meta_string::MetaStringEncoder;
+use crate::buffer::{Reader, Writer};
+use crate::error::Error;
+use crate::types::FieldType;
+
+//todo backward/forward compatibility
+#[allow(dead_code)]
+pub struct FieldInfo {
+    tag_id: u32,
+    field_name: String,
+    field_type: FieldType,
+}
+
+impl FieldInfo {
+    pub fn new(field_name: &str, field_type: FieldType) -> FieldInfo {
+        FieldInfo {
+            field_name: field_name.to_string(),
+            field_type,
+            tag_id: 0,
+        }
+    }
+
+    fn to_bytes(&self) -> Result<Vec<u8>, Error> {
+        let mut writer = Writer::default();
+        let meta_string = MetaStringEncoder::new().encode(&self.field_name)?;
+        let mut header = 1 << 2;
+        let encoded = meta_string.bytes.as_slice();
+        let size = (encoded.len() - 1) as u32;
+        header |= (meta_string.encoding as u8) << 3;
+        let big_size = size >= 7;
+        if big_size {
+            header |= 0b11100000;
+            writer.u8(header);
+            writer.var_int32((size - 7) as i32);
+        } else {
+            header |= (size << 5) as u8;
+            writer.u8(header);
+        }
+        writer.bytes(encoded);
+        Ok(writer.dump())
+    }
+}
+
+struct TypeMetaLayer {
+    type_id: u32,
+    field_info: Vec<FieldInfo>,
+}
+
+impl TypeMetaLayer {
+    fn to_bytes(&self) -> Result<Vec<u8>, Error> {
+        let mut writer = Writer::default();
+        writer.var_int32(self.field_info.len() as i32);
+        writer.var_int32(self.type_id as i32);
+        for field in self.field_info.iter() {
+            writer.bytes(field.to_bytes()?.as_slice());
+        }
+        Ok(writer.dump())
+    }
+}
+
+pub struct TypeMeta {
+    hash: u64,
+    layers: Vec<TypeMetaLayer>,
+}
+
+impl TypeMeta {
+    pub fn from_fields(type_id: u32, field_info: Vec<FieldInfo>) -> TypeMeta {
+        TypeMeta {
+            hash: 0,
+            layers: vec![TypeMetaLayer {
+                type_id,
+                field_info,
+            }],
+        }
+    }
+
+    pub fn to_bytes(&self) -> Result<Vec<u8>, Error> {
+        let mut writer = Writer::default();
+        writer.u64((self.hash << 4) | (self.layers.len() as u64 & 0b1111));
+        for layer in self.layers.iter() {
+            writer.bytes(layer.to_bytes()?.as_slice());
+        }
+        Ok(writer.dump())
+    }
+
+    pub fn read_hash_from_bytes(reader: &mut Reader) -> u64 {
+        reader.u64() >> 7
+    }
+
+    pub fn from_bytes(_reader: &mut Reader) -> TypeMeta {
+        TypeMeta {
+            hash: 0,
+            layers: Vec::new(),
+        }
+    }
+}
diff --git a/rust/fury-core/src/read_state.rs b/rust/fury-core/src/read_state.rs
new file mode 100644
index 00000000..eaffdaa4
--- /dev/null
+++ b/rust/fury-core/src/read_state.rs
@@ -0,0 +1,66 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::buffer::Reader;
+use super::types::Language;
+use crate::error::Error;
+use crate::fury::Fury;
+
+pub struct ReadState<'de, 'bf: 'de> {
+    pub reader: Reader<'bf>,
+    pub tags: Vec<&'de str>,
+    pub fury: &'de Fury,
+}
+
+impl<'de, 'bf: 'de> ReadState<'de, 'bf> {
+    pub fn new(fury: &'de Fury, reader: Reader<'bf>) -> ReadState<'de, 'bf> {
+        ReadState {
+            reader,
+            tags: Vec::new(),
+            fury,
+        }
+    }
+
+    pub fn get_fury(&self) -> &Fury {
+        self.fury
+    }
+
+    pub fn head(&mut self) -> Result<(), Error> {
+        let _bitmap = self.reader.u8();
+        let _language: Language = self.reader.u8().try_into()?;
+        self.reader.skip(8); // native offset and size
+        Ok(())
+    }
+
+    pub fn read_tag(&mut self) -> Result<&str, Error> {
+        const USESTRINGVALUE: u8 = 0;
+        const USESTRINGID: u8 = 1;
+        let tag_type = self.reader.u8();
+        if tag_type == USESTRINGID {
+            Ok(self.tags[self.reader.i16() as usize])
+        } else if tag_type == USESTRINGVALUE {
+            self.reader.skip(8); // todo tag hash
+            let len = self.reader.i16();
+            let tag: &str =
+                unsafe { std::str::from_utf8_unchecked(self.reader.bytes(len 
as usize)) };
+            self.tags.push(tag);
+            Ok(tag)
+        } else {
+            Err(Error::TagType(tag_type))
+        }
+    }
+}
diff --git a/rust/fury/src/row/bit_util.rs b/rust/fury-core/src/row/bit_util.rs
similarity index 100%
rename from rust/fury/src/row/bit_util.rs
rename to rust/fury-core/src/row/bit_util.rs
diff --git a/rust/fury/src/row/mod.rs b/rust/fury-core/src/row/mod.rs
similarity index 100%
rename from rust/fury/src/row/mod.rs
rename to rust/fury-core/src/row/mod.rs
diff --git a/rust/fury/src/row/reader.rs b/rust/fury-core/src/row/reader.rs
similarity index 100%
rename from rust/fury/src/row/reader.rs
rename to rust/fury-core/src/row/reader.rs
diff --git a/rust/fury/src/row/row.rs b/rust/fury-core/src/row/row.rs
similarity index 99%
rename from rust/fury/src/row/row.rs
rename to rust/fury-core/src/row/row.rs
index be0f6591..baeb33f5 100644
--- a/rust/fury/src/row/row.rs
+++ b/rust/fury-core/src/row/row.rs
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::{buffer::Writer, Error};
+use crate::{buffer::Writer, error::Error};
 use byteorder::{ByteOrder, LittleEndian};
 use chrono::{DateTime, Days, NaiveDate, NaiveDateTime};
 use std::collections::BTreeMap;
diff --git a/rust/fury/src/row/writer.rs b/rust/fury-core/src/row/writer.rs
similarity index 100%
rename from rust/fury/src/row/writer.rs
rename to rust/fury-core/src/row/writer.rs
diff --git a/rust/fury-core/src/serializer.rs b/rust/fury-core/src/serializer.rs
new file mode 100644
index 00000000..a5d4f8a7
--- /dev/null
+++ b/rust/fury-core/src/serializer.rs
@@ -0,0 +1,86 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use crate::error::Error;
+use crate::read_state::ReadState;
+use crate::types::{FieldType, RefFlag};
+use crate::write_state::WriteState;
+
+pub trait Serializer
+where
+    Self: Sized,
+{
+    /// The fixed memory size of the Type.
+    /// Avoid the memory check, which would hurt performance.
+    fn reserved_space() -> usize;
+
+    /// Write the data into the buffer.
+    fn write(&self, serializer: &mut WriteState);
+
+    /// Entry point of the serialization.
+    ///
+    /// Step 1: write the type flag and type flag into the buffer.
+    /// Step 2: invoke the write function to write the Rust object.
+    fn serialize(&self, serializer: &mut WriteState) {
+        // ref flag
+        serializer.writer.i8(RefFlag::NotNullValue as i8);
+        // type
+        serializer.writer.i16(Self::ty() as i16);
+        self.write(serializer);
+    }
+
+    fn read(deserializer: &mut ReadState) -> Result<Self, Error>;
+
+    fn deserialize(deserializer: &mut ReadState) -> Result<Self, Error> {
+        // ref flag
+        let ref_flag = deserializer.reader.i8();
+
+        if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == 
(RefFlag::RefValue as i8) {
+            // type_id
+            let type_id = deserializer.reader.i16();
+            let ty = Self::ty();
+            if type_id != ty as i16 {
+                Err(Error::FieldType {
+                    expected: ty,
+                    actial: type_id,
+                })
+            } else {
+                Ok(Self::read(deserializer)?)
+            }
+        } else if ref_flag == (RefFlag::Null as i8) {
+            Err(Error::Null)
+        } else if ref_flag == (RefFlag::Ref as i8) {
+            Err(Error::Ref)
+        } else {
+            Err(Error::BadRefFlag)
+        }
+    }
+
+    fn ty() -> FieldType;
+
+    fn hash() -> u32 {
+        0
+    }
+
+    fn tag() -> &'static str {
+        ""
+    }
+
+    fn type_def() -> &'static [u8] {
+        &[]
+    }
+}
diff --git a/rust/fury/src/types.rs b/rust/fury-core/src/types.rs
similarity index 60%
rename from rust/fury/src/types.rs
rename to rust/fury-core/src/types.rs
index 7c4647d7..47f6cf57 100644
--- a/rust/fury/src/types.rs
+++ b/rust/fury-core/src/types.rs
@@ -15,125 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use std::{
-    collections::{HashMap, HashSet},
-    mem,
-};
-
-use chrono::{NaiveDate, NaiveDateTime};
-
-use crate::Error;
-
-pub trait FuryMeta {
-    fn ty() -> FieldType;
-
-    fn vec_ty() -> FieldType {
-        FieldType::ARRAY
-    }
-
-    fn hash() -> u32 {
-        0
-    }
-
-    fn tag() -> &'static str {
-        ""
-    }
-
-    fn is_vec() -> bool {
-        false
-    }
-}
-
-macro_rules! impl_number_meta {
-    ($expr: expr, $tt: tt) => {
-        impl FuryMeta for $tt {
-            fn ty() -> FieldType {
-                $expr
-            }
-        }
-    };
-}
-
-macro_rules! impl_primitive_array_meta {
-    ($ty: expr, $vec_ty: expr, $tt: tt) => {
-        impl FuryMeta for $tt {
-            fn ty() -> FieldType {
-                $ty
-            }
-
-            fn vec_ty() -> FieldType {
-                $vec_ty
-            }
-        }
-    };
-}
-
-impl<T1, T2> FuryMeta for HashMap<T1, T2> {
-    fn ty() -> FieldType {
-        FieldType::MAP
-    }
-}
-
-impl<T> FuryMeta for HashSet<T> {
-    fn ty() -> FieldType {
-        FieldType::FurySet
-    }
-}
-
-impl FuryMeta for u8 {
-    fn ty() -> FieldType {
-        FieldType::UINT8
-    }
-    fn vec_ty() -> FieldType {
-        FieldType::BINARY
-    }
-}
-
-impl FuryMeta for NaiveDateTime {
-    fn ty() -> FieldType {
-        FieldType::TIMESTAMP
-    }
-}
-
-impl FuryMeta for NaiveDate {
-    fn ty() -> FieldType {
-        FieldType::DATE
-    }
-}
-
-impl_number_meta!(FieldType::UINT16, u16);
-impl_number_meta!(FieldType::UINT32, u32);
-impl_number_meta!(FieldType::UINT64, u64);
-impl_number_meta!(FieldType::INT8, i8);
-
-// special type array
-impl_primitive_array_meta!(FieldType::BOOL, FieldType::FuryPrimitiveBoolArray, 
bool);
-impl_primitive_array_meta!(FieldType::INT16, 
FieldType::FuryPrimitiveShortArray, i16);
-impl_primitive_array_meta!(FieldType::INT32, FieldType::FuryPrimitiveIntArray, 
i32);
-impl_primitive_array_meta!(FieldType::INT64, 
FieldType::FuryPrimitiveLongArray, i64);
-impl_primitive_array_meta!(FieldType::FLOAT, 
FieldType::FuryPrimitiveFloatArray, f32);
-impl_primitive_array_meta!(FieldType::DOUBLE, 
FieldType::FuryPrimitiveDoubleArray, f64);
-impl_primitive_array_meta!(FieldType::STRING, FieldType::FuryStringArray, 
String);
-
-impl<T: FuryMeta> FuryMeta for Vec<T> {
-    fn ty() -> FieldType {
-        FieldType::ARRAY
-    }
-
-    fn is_vec() -> bool {
-        true
-    }
-}
-
-impl<T: FuryMeta> FuryMeta for Option<T> {
-    fn vec_ty() -> FieldType {
-        T::vec_ty()
-    }
-
-    fn ty() -> FieldType {
-        T::ty()
-    }
-}
+use crate::error::Error;
+use std::mem;
 
 #[allow(dead_code)]
 pub enum StringFlag {
@@ -182,6 +65,8 @@ pub enum FieldType {
     FuryStringArray = 264,
 }
 
+pub trait FuryGeneralList {}
+
 const MAX_UNT32: u64 = (1 << 31) - 1;
 
 // todo: struct hash
@@ -219,10 +104,10 @@ pub fn compute_field_hash(hash: u32, id: i16) -> u32 {
     new_hash as u32
 }
 
-pub fn compute_struct_hash(props: Vec<(&str, FieldType, &str)>) -> u32 {
+pub fn compute_struct_hash(props: Vec<(&str, FieldType)>) -> u32 {
     let mut hash = 17;
     props.iter().for_each(|prop| {
-        let (_name, ty, _tag) = prop;
+        let (_name, ty) = prop;
         hash = match ty {
             FieldType::ARRAY | FieldType::MAP => compute_field_hash(hash, *ty 
as i16),
             _ => hash,
@@ -255,6 +140,11 @@ pub enum Language {
     Rust = 6,
 }
 
+pub enum Mode {
+    SchemaConsistent,
+    Compatible,
+}
+
 impl TryFrom<u8> for Language {
     type Error = Error;
 
@@ -267,7 +157,7 @@ impl TryFrom<u8> for Language {
             4 => Ok(Language::Go),
             5 => Ok(Language::Javascript),
             6 => Ok(Language::Rust),
-            _ => Err(Error::UnsupportLanguageCode { code: num }),
+            _ => Err(Error::UnsupportedLanguageCode { code: num }),
         }
     }
 }
diff --git a/rust/fury/src/util.rs b/rust/fury-core/src/util.rs
similarity index 100%
rename from rust/fury/src/util.rs
rename to rust/fury-core/src/util.rs
diff --git a/rust/fury-core/src/write_state.rs 
b/rust/fury-core/src/write_state.rs
new file mode 100644
index 00000000..9a756000
--- /dev/null
+++ b/rust/fury-core/src/write_state.rs
@@ -0,0 +1,82 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::buffer::Writer;
+use super::types::{config_flags, Language, SIZE_OF_REF_AND_TYPE};
+use crate::fury::Fury;
+use crate::meta::MetaWriterStore;
+use crate::serializer::Serializer;
+
+pub struct WriteState<'se> {
+    pub writer: &'se mut Writer,
+    pub tags: Vec<&'static str>,
+    fury: &'se Fury,
+    meta_store: MetaWriterStore<'se>,
+}
+
+impl<'se> WriteState<'se> {
+    pub fn new(fury: &'se Fury, writer: &'se mut Writer) -> WriteState<'se> {
+        WriteState {
+            writer,
+            tags: Vec::new(),
+            fury,
+            meta_store: MetaWriterStore::default(),
+        }
+    }
+
+    pub fn push_meta(&mut self, type_id: u32, type_def: &'static [u8]) {
+        self.meta_store.push(type_id, type_def);
+    }
+
+    pub fn get_fury(&self) -> &Fury {
+        self.fury
+    }
+
+    pub fn write_tag(&mut self, tag: &'static str) {
+        const USESTRINGVALUE: u8 = 0;
+        const USESTRINGID: u8 = 1;
+
+        let mayby_idx = self.tags.iter().position(|x| *x == tag);
+        match mayby_idx {
+            Some(idx) => {
+                self.writer.u8(USESTRINGID);
+                self.writer.i16(idx as i16);
+            }
+            None => {
+                self.writer.u8(USESTRINGVALUE);
+                self.writer.skip(8); // todo tag hash
+                self.writer.i16(tag.len() as i16);
+                self.writer.bytes(tag.as_bytes());
+            }
+        };
+    }
+
+    pub fn head<T: Serializer>(&mut self) -> &Self {
+        const HEAD_SIZE: usize = 10;
+        self.writer
+            .reserve(<T as Serializer>::reserved_space() + 
SIZE_OF_REF_AND_TYPE + HEAD_SIZE);
+
+        let mut bitmap = 0;
+        bitmap |= config_flags::IS_LITTLE_ENDIAN_FLAG;
+        bitmap |= config_flags::IS_CROSS_LANGUAGE_FLAG;
+        self.writer.u8(bitmap);
+        self.writer.u8(Language::Rust as u8);
+        self.writer.skip(4); // native offset
+        self.writer.skip(4); // native size
+        self
+    }
+}
diff --git a/rust/fury/tests/de.rs b/rust/fury-core/tests/de.rs
similarity index 100%
rename from rust/fury/tests/de.rs
rename to rust/fury-core/tests/de.rs
diff --git a/rust/fury-derive/Cargo.toml b/rust/fury-derive/Cargo.toml
index ced37343..1707ee95 100644
--- a/rust/fury-derive/Cargo.toml
+++ b/rust/fury-derive/Cargo.toml
@@ -26,6 +26,7 @@ proc-macro = true
 
 [dependencies]
 proc-macro2 = { default-features = false, version = "1.0" }
+fury-core = { path = "../fury-core"}
 syn = { default-features = false, version = "2.0", features = [
     "parsing",
     "proc-macro",
diff --git a/rust/fury-derive/src/fury_meta.rs 
b/rust/fury-derive/src/fury_meta.rs
index ed251d28..47510998 100644
--- a/rust/fury-derive/src/fury_meta.rs
+++ b/rust/fury-derive/src/fury_meta.rs
@@ -25,7 +25,7 @@ pub fn sorted_fields(fields: &Fields) -> Vec<&Field> {
     fields
 }
 
-pub fn derive_fury_meta(ast: &syn::DeriveInput, tag: String) -> TokenStream {
+pub fn derive_serializer(ast: &syn::DeriveInput, tag: &String) -> TokenStream {
     let name = &ast.ident;
     let fields = match &ast.data {
         syn::Data::Struct(s) => sorted_fields(&s.fields),
@@ -33,53 +33,23 @@ pub fn derive_fury_meta(ast: &syn::DeriveInput, tag: 
String) -> TokenStream {
             panic!("only struct be supported")
         }
     };
-    let props = fields.iter().map(|field| {
+
+    let name_hash: proc_macro2::Ident =
+        syn::Ident::new(&format!("HASH_{}", name).to_uppercase(), name.span());
+
+    let field_infos = fields.iter().map(|field| {
         let ty = &field.ty;
         let name = format!("{}", field.ident.as_ref().expect("should be field 
name"));
         quote! {
-            (#name, <#ty as fury::__derive::FuryMeta>::ty(), <#ty as 
fury::__derive::FuryMeta>::tag())
+            fury_core::meta::FieldInfo::new(#name, <#ty as 
fury_core::serializer::Serializer>::ty())
         }
     });
-    let name_hash_static: proc_macro2::Ident =
-        syn::Ident::new(&format!("HASH_{}", name).to_uppercase(), name.span());
-
-    let gen = quote! {
-
-        lazy_static::lazy_static! {
-            static ref #name_hash_static: u32 = 
fury::__derive::compute_struct_hash(vec![#(#props),*]);
-        }
-
-        impl fury::__derive::FuryMeta for #name {
-            fn tag() -> &'static str {
-                #tag
-            }
-
-            fn hash() -> u32 {
-                *(#name_hash_static)
-            }
-
-            fn ty() -> fury::__derive::FieldType {
-                fury::__derive::FieldType::FuryTypeTag
-            }
-        }
-    };
-    gen.into()
-}
-
-pub fn derive_serialize(ast: &syn::DeriveInput) -> TokenStream {
-    let name = &ast.ident;
-    let fields = match &ast.data {
-        syn::Data::Struct(s) => sorted_fields(&s.fields),
-        _ => {
-            panic!("only struct be supported")
-        }
-    };
 
     let accessor_exprs = fields.iter().map(|field| {
         let ty = &field.ty;
         let ident = &field.ident;
         quote! {
-            <#ty as fury::__derive::Serialize>::serialize(&self.#ident, 
serializer);
+            <#ty as 
fury_core::serializer::Serializer>::serialize(&self.#ident, serializer);
         }
     });
 
@@ -87,65 +57,84 @@ pub fn derive_serialize(ast: &syn::DeriveInput) -> 
TokenStream {
         let ty = &field.ty;
         // each field have one byte ref tag and two byte type id
         quote! {
-            <#ty as fury::__derive::Serialize>::reserved_space() + 
fury::__derive::SIZE_OF_REF_AND_TYPE
+            <#ty as fury_core::serializer::Serializer>::reserved_space() + 
fury_core::types::SIZE_OF_REF_AND_TYPE
         }
     });
 
     let tag_bytelen = format!("{}", name).len();
 
-    let gen = quote! {
-        impl fury::__derive::Serialize for #name {
-            fn write(&self, serializer: &mut fury::__derive::SerializerState) {
-                // write tag string
-                serializer.write_tag(<#name as 
fury::__derive::FuryMeta>::tag());
-                // write tag hash
-                serializer.writer.u32(<#name as 
fury::__derive::FuryMeta>::hash());
-                // write fields
-                #(#accessor_exprs)*
-            }
-
-            fn reserved_space() -> usize {
-                // struct have four byte hash
-                #tag_bytelen + 4 + #(#reserved_size_exprs)+*
-            }
-        }
-    };
-    gen.into()
-}
-
-pub fn derive_deserilize(ast: &syn::DeriveInput) -> TokenStream {
-    let name = &ast.ident;
-    let fields = match &ast.data {
-        syn::Data::Struct(s) => sorted_fields(&s.fields),
-        _ => {
-            panic!("only struct be supported")
-        }
-    };
-
     let exprs = fields.iter().map(|field| {
         let ty = &field.ty;
         let ident = &field.ident;
         quote! {
-            #ident: <#ty as 
fury::__derive::Deserialize>::deserialize(deserializer)?
+            #ident: <#ty as 
fury_core::serializer::Serializer>::deserialize(state)?
+        }
+    });
+
+    let props = fields.iter().map(|field| {
+        let ty = &field.ty;
+        let name = format!("{}", field.ident.as_ref().expect("should be field 
name"));
+        quote! {
+            (#name, <#ty as fury_core::serializer::Serializer>::ty())
         }
     });
 
     let gen = quote! {
-        impl<'de> fury::__derive::Deserialize for #name {
-            fn read(deserializer: &mut fury::__derive::DeserializerState) -> 
Result<Self, fury::__derive::Error> {
+        impl fury_core::types::FuryGeneralList for #name {}
+        impl fury_core::serializer::Serializer for #name {
+            fn tag() -> &'static str {
+                #tag
+            }
+
+            fn hash() -> u32 {
+                lazy_static::lazy_static! {
+                    static ref #name_hash: u32 = 
fury_core::types::compute_struct_hash(vec![#(#props),*]);
+                }
+                *(#name_hash)
+            }
+
+            fn type_def() -> &'static [u8] {
+                lazy_static::lazy_static! {
+                    static ref type_definition: Vec<u8> = 
fury_core::meta::TypeMeta::from_fields(
+                        0,
+                        vec![#(#field_infos),*]
+                    ).to_bytes().unwrap();
+                }
+                type_definition.as_slice()
+            }
+
+            fn ty() -> fury_core::types::FieldType {
+                fury_core::types::FieldType::FuryTypeTag
+            }
+
+            fn write(&self, serializer: &mut 
fury_core::write_state::WriteState) {
+                // write tag string
+                serializer.write_tag(<#name as 
fury_core::serializer::Serializer>::tag());
+                // write tag hash
+                serializer.writer.u32(<#name as 
fury_core::serializer::Serializer>::hash());
+                // write fields
+                #(#accessor_exprs)*
+            }
+
+            fn read(state: &mut fury_core::read_state::ReadState) -> 
Result<Self, fury_core::error::Error> {
                 // read tag string
-                deserializer.read_tag()?;
+                state.read_tag()?;
                 // read tag hash
-                let hash = deserializer.reader.u32();
-                let expected = <#name as fury::__derive::FuryMeta>::hash();
+                let hash = state.reader.u32();
+                let expected = <#name as 
fury_core::serializer::Serializer>::hash();
                 if(hash != expected) {
-                    Err(fury::__derive::Error::StructHash{ expected, actial: 
hash })
+                    Err(fury_core::error::Error::StructHash{ expected, actial: 
hash })
                 } else {
                     Ok(Self {
                         #(#exprs),*
                     })
                 }
             }
+
+            fn reserved_space() -> usize {
+                // struct have four byte hash
+                #tag_bytelen + 4 + #(#reserved_size_exprs)+*
+            }
         }
     };
     gen.into()
diff --git a/rust/fury-derive/src/fury_row.rs b/rust/fury-derive/src/fury_row.rs
index 70304fc7..20b55aea 100644
--- a/rust/fury-derive/src/fury_row.rs
+++ b/rust/fury-derive/src/fury_row.rs
@@ -35,7 +35,7 @@ pub fn derive_row(ast: &syn::DeriveInput) -> TokenStream {
 
         quote! {
             let mut callback_info = struct_writer.write_start(#index);
-            <#ty as fury::__derive::Row<'a>>::write(&v.#ident, 
struct_writer.get_writer());
+            <#ty as fury_core::row::Row<'a>>::write(&v.#ident, 
struct_writer.get_writer());
             struct_writer.write_end(callback_info);
         }
     });
@@ -46,9 +46,9 @@ pub fn derive_row(ast: &syn::DeriveInput) -> TokenStream {
         let getter_name: proc_macro2::Ident = syn::Ident::new(&format!("{}", 
ident), ident.span());
 
         quote! {
-            pub fn #getter_name(&self) -> <#ty as 
fury::__derive::Row<'a>>::ReadResult {
+            pub fn #getter_name(&self) -> <#ty as 
fury_core::row::Row<'a>>::ReadResult {
                 let bytes = self.struct_data.get_field_bytes(#index);
-                <#ty as fury::__derive::Row<'a>>::cast(bytes)
+                <#ty as fury_core::row::Row<'a>>::cast(bytes)
             }
         }
     });
@@ -60,24 +60,24 @@ pub fn derive_row(ast: &syn::DeriveInput) -> TokenStream {
 
     let gen = quote! {
         struct #getter<'a> {
-            struct_data: fury::__derive::StructViewer<'a>
+            struct_data: fury_core::row::StructViewer<'a>
         }
 
         impl<'a> #getter<'a> {
             #(#getter_exprs)*
         }
 
-        impl<'a> fury::__derive::Row<'a> for #name {
+        impl<'a> fury_core::row::Row<'a> for #name {
 
             type ReadResult = #getter<'a>;
 
-            fn write(v: &Self, writer: &mut fury::__derive::Writer) {
-                let mut struct_writer = 
fury::__derive::StructWriter::new(#num_fields, writer);
+            fn write(v: &Self, writer: &mut fury_core::buffer::Writer) {
+                let mut struct_writer = 
fury_core::row::StructWriter::new(#num_fields, writer);
                 #(#write_exprs);*;
             }
 
             fn cast(bytes: &'a [u8]) -> Self::ReadResult {
-                #getter{ struct_data: fury::__derive::StructViewer::new(bytes, 
#num_fields) }
+                #getter{ struct_data: fury_core::row::StructViewer::new(bytes, 
#num_fields) }
             }
         }
     };
diff --git a/rust/fury-derive/src/lib.rs b/rust/fury-derive/src/lib.rs
index e18ca210..a72e7a42 100644
--- a/rust/fury-derive/src/lib.rs
+++ b/rust/fury-derive/src/lib.rs
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use fury_meta::{derive_deserilize, derive_fury_meta, derive_serialize};
+use fury_meta::derive_serializer;
 use fury_row::derive_row;
 use proc_macro::TokenStream;
 use syn::{parse_macro_input, DeriveInput};
@@ -38,12 +38,7 @@ pub fn proc_macro_derive_fury_meta(input: 
proc_macro::TokenStream) -> TokenStrea
             panic!("tag should be string")
         }
     };
-    let mut token_stream = derive_fury_meta(&input, tag);
-    // append serialize impl
-    token_stream.extend(derive_serialize(&input));
-    // append deserialize impl
-    token_stream.extend(derive_deserilize(&input));
-    token_stream
+    derive_serializer(&input, &tag)
 }
 
 #[proc_macro_derive(FuryRow)]
diff --git a/rust/fury/Cargo.toml b/rust/fury/Cargo.toml
index bba04afb..1335f701 100644
--- a/rust/fury/Cargo.toml
+++ b/rust/fury/Cargo.toml
@@ -15,28 +15,18 @@
 # specific language governing permissions and limitations
 # under the License.
 
+
 [package]
 name = "fury"
 version.workspace = true
-edition.workspace = true
 rust-version.workspace = true
+license.workspace = true
+readme.workspace = true
+repository.workspace = true
+edition.workspace = true
+keywords.workspace = true
+categories.workspace = true
 
 [dependencies]
-proc-macro2 = { default-features = false, version = "1.0" }
-syn = { default-features = false, version = "2.0", features = ["full", "fold"] 
}
-quote = { default-features = false, version = "1.0" }
-fury-derive = { path = "../fury-derive" }
-lazy_static = { version = "1.4" }
-byteorder = { version = "1.4" }
-chrono = "0.4"
-thiserror = { default-features = false, version = "1.0" }
-
-
-[[bench]]
-name = "simd_bench"
-harness = false
-
-
-[dev-dependencies]
-criterion = "0.5.1"
-rand = "0.8.5"
\ No newline at end of file
+fury-core = { path = "../fury-core"}
+fury-derive = { path = "../fury-derive"}
diff --git a/rust/fury/src/deserializer.rs b/rust/fury/src/deserializer.rs
deleted file mode 100644
index 0ca8f343..00000000
--- a/rust/fury/src/deserializer.rs
+++ /dev/null
@@ -1,269 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use super::buffer::Reader;
-use super::types::Language;
-use crate::{
-    error::Error,
-    types::{FuryMeta, RefFlag},
-};
-use chrono::{DateTime, Days, NaiveDate, NaiveDateTime, TimeZone, Utc};
-use std::{
-    collections::{HashMap, HashSet},
-    mem,
-};
-
-fn from_u8_slice<T: Clone>(slice: &[u8]) -> Vec<T> {
-    let byte_len = slice.len() / mem::size_of::<T>();
-    unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::<T>(), byte_len) 
}.to_vec()
-}
-
-pub trait Deserialize
-where
-    Self: Sized + FuryMeta,
-{
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error>;
-
-    fn read_vec(deserializer: &mut DeserializerState) -> Result<Vec<Self>, 
Error> {
-        // length
-        let len = deserializer.reader.var_int32();
-        // value
-        let mut result = Vec::new();
-        for _ in 0..len {
-            result.push(Self::deserialize(deserializer)?);
-        }
-        Ok(result)
-    }
-
-    fn deserialize(deserializer: &mut DeserializerState) -> Result<Self, 
Error> {
-        // ref flag
-        let ref_flag = deserializer.reader.i8();
-
-        if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == 
(RefFlag::RefValue as i8) {
-            // type_id
-            let type_id = deserializer.reader.i16();
-            let ty = if Self::is_vec() {
-                Self::vec_ty()
-            } else {
-                Self::ty()
-            };
-            if type_id != ty as i16 {
-                Err(Error::FieldType {
-                    expected: ty,
-                    actial: type_id,
-                })
-            } else {
-                Ok(Self::read(deserializer)?)
-            }
-        } else if ref_flag == (RefFlag::Null as i8) {
-            Err(Error::Null)
-        } else if ref_flag == (RefFlag::Ref as i8) {
-            Err(Error::Ref)
-        } else {
-            Err(Error::BadRefFlag)
-        }
-    }
-}
-
-macro_rules! impl_num_deserialize {
-    ($name: ident, $ty:tt) => {
-        impl Deserialize for $ty {
-            fn read(deserializer: &mut DeserializerState) -> Result<Self, 
Error> {
-                Ok(deserializer.reader.$name())
-            }
-        }
-    };
-}
-
-macro_rules! impl_num_deserialize_and_pritimive_vec {
-    ($name: ident, $ty:tt) => {
-        impl Deserialize for $ty {
-            fn read(deserializer: &mut DeserializerState) -> Result<Self, 
Error> {
-                Ok(deserializer.reader.$name())
-            }
-
-            fn read_vec(deserializer: &mut DeserializerState) -> 
Result<Vec<Self>, Error> {
-                // length
-                let len = (deserializer.reader.var_int32() as usize) * 
mem::size_of::<$ty>();
-                Ok(from_u8_slice::<$ty>(
-                    deserializer.reader.bytes(len as usize),
-                ))
-            }
-        }
-    };
-}
-
-impl_num_deserialize!(u16, u16);
-impl_num_deserialize!(u32, u32);
-impl_num_deserialize!(u64, u64);
-impl_num_deserialize!(i8, i8);
-
-impl_num_deserialize_and_pritimive_vec!(u8, u8);
-impl_num_deserialize_and_pritimive_vec!(i16, i16);
-impl_num_deserialize_and_pritimive_vec!(i32, i32);
-impl_num_deserialize_and_pritimive_vec!(i64, i64);
-impl_num_deserialize_and_pritimive_vec!(f32, f32);
-impl_num_deserialize_and_pritimive_vec!(f64, f64);
-
-impl Deserialize for String {
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error> {
-        let len = deserializer.reader.var_int32();
-        Ok(deserializer.reader.string(len as usize))
-    }
-}
-
-impl Deserialize for bool {
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error> {
-        Ok(deserializer.reader.u8() == 1)
-    }
-}
-
-impl<T1: Deserialize + Eq + std::hash::Hash, T2: Deserialize> Deserialize for 
HashMap<T1, T2> {
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error> {
-        // length
-        let len = deserializer.reader.var_int32();
-        let mut result = HashMap::new();
-        // key-value
-        for _ in 0..len {
-            result.insert(
-                <T1 as Deserialize>::deserialize(deserializer)?,
-                <T2 as Deserialize>::deserialize(deserializer)?,
-            );
-        }
-        Ok(result)
-    }
-}
-
-impl<T: Deserialize + Eq + std::hash::Hash> Deserialize for HashSet<T> {
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error> {
-        // length
-        let len = deserializer.reader.var_int32();
-        let mut result = HashSet::new();
-        // key-value
-        for _ in 0..len {
-            result.insert(<T as Deserialize>::deserialize(deserializer)?);
-        }
-        Ok(result)
-    }
-}
-
-impl Deserialize for NaiveDateTime {
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error> {
-        let timestamp = deserializer.reader.u64();
-        let ret = DateTime::from_timestamp_millis(timestamp as i64).map(|dt| 
dt.naive_utc());
-        match ret {
-            Some(r) => Ok(r),
-            None => Err(Error::NaiveDateTime),
-        }
-    }
-}
-
-impl<T: Deserialize> Deserialize for Vec<T> {
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error> {
-        T::read_vec(deserializer)
-    }
-}
-
-impl<T: Deserialize> Deserialize for Option<T> {
-    fn read(deserializer: &mut DeserializerState) -> Result<Self, Error> {
-        Ok(Some(T::read(deserializer)?))
-    }
-
-    fn deserialize(deserializer: &mut DeserializerState) -> Result<Self, 
Error> {
-        // ref flag
-        let ref_flag = deserializer.reader.i8();
-
-        if ref_flag == (RefFlag::NotNullValue as i8) || ref_flag == 
(RefFlag::RefValue as i8) {
-            // type_id
-            let type_id = deserializer.reader.i16();
-
-            if type_id != <Self as FuryMeta>::ty() as i16 {
-                Err(Error::FieldType {
-                    expected: <Self as FuryMeta>::ty(),
-                    actial: type_id,
-                })
-            } else {
-                Ok(Self::read(deserializer)?)
-            }
-        } else if ref_flag == (RefFlag::Null as i8) {
-            Ok(None)
-        } else if ref_flag == (RefFlag::Ref as i8) {
-            Err(Error::Ref)
-        } else {
-            Err(Error::BadRefFlag)
-        }
-    }
-}
-
-lazy_static::lazy_static!(
-    static ref EPOCH: DateTime<Utc> = Utc.with_ymd_and_hms(1970, 1, 1, 0, 0, 
0).unwrap();
-);
-
-impl Deserialize for NaiveDate {
-    fn read(serializer: &mut DeserializerState) -> Result<Self, Error> {
-        let days = serializer.reader.u64();
-        match EPOCH.checked_add_days(Days::new(days)) {
-            Some(value) => Ok(value.date_naive()),
-            None => Err(Error::NaiveDate),
-        }
-    }
-}
-pub struct DeserializerState<'de, 'bf: 'de> {
-    pub reader: Reader<'bf>,
-    pub tags: Vec<&'de str>,
-}
-
-impl<'de, 'bf: 'de> DeserializerState<'de, 'bf> {
-    fn new(reader: Reader<'bf>) -> DeserializerState<'de, 'bf> {
-        DeserializerState {
-            reader,
-            tags: Vec::new(),
-        }
-    }
-
-    fn head(&mut self) -> Result<(), Error> {
-        let _bitmap = self.reader.u8();
-        let _language: Language = self.reader.u8().try_into()?;
-        self.reader.skip(8); // native offset and size
-        Ok(())
-    }
-
-    pub fn read_tag(&mut self) -> Result<&str, Error> {
-        const USESTRINGVALUE: u8 = 0;
-        const USESTRINGID: u8 = 1;
-        let tag_type = self.reader.u8();
-        if tag_type == USESTRINGID {
-            Ok(self.tags[self.reader.i16() as usize])
-        } else if tag_type == USESTRINGVALUE {
-            self.reader.skip(8); // todo tag hash
-            let len = self.reader.i16();
-            let tag: &str =
-                unsafe { std::str::from_utf8_unchecked(self.reader.bytes(len 
as usize)) };
-            self.tags.push(tag);
-            Ok(tag)
-        } else {
-            Err(Error::TagType(tag_type))
-        }
-    }
-}
-
-pub fn from_buffer<T: Deserialize>(bf: &[u8]) -> Result<T, Error> {
-    let reader = Reader::new(bf);
-    let mut deserializer = DeserializerState::new(reader);
-    deserializer.head()?;
-    <T as Deserialize>::deserialize(&mut deserializer)
-}
diff --git a/rust/fury/src/lib.rs b/rust/fury/src/lib.rs
index 248de27d..b1b8a60d 100644
--- a/rust/fury/src/lib.rs
+++ b/rust/fury/src/lib.rs
@@ -15,28 +15,4 @@
 // specific language governing permissions and limitations
 // under the License.
 
-mod buffer;
-mod deserializer;
-mod error;
-mod meta;
-mod row;
-mod serializer;
-mod types;
-mod util;
-
-pub use deserializer::from_buffer;
-pub use error::Error;
-pub use fury_derive::*;
-pub use meta::{Encoding, MetaStringDecoder, MetaStringEncoder};
-pub use row::{from_row, to_row};
-pub use serializer::to_buffer;
-pub use util::to_utf8;
-
-pub mod __derive {
-    pub use crate::buffer::{Reader, Writer};
-    pub use crate::deserializer::{Deserialize, DeserializerState};
-    pub use crate::row::{ArrayViewer, ArrayWriter, Row, StructViewer, 
StructWriter};
-    pub use crate::serializer::{Serialize, SerializerState};
-    pub use crate::types::{compute_struct_hash, FieldType, FuryMeta, 
SIZE_OF_REF_AND_TYPE};
-    pub use crate::Error;
-}
+pub use fury_core::{error::Error, fury::Fury, row::from_row, row::to_row};
diff --git a/rust/fury/src/serializer.rs b/rust/fury/src/serializer.rs
deleted file mode 100644
index 3c253ce2..00000000
--- a/rust/fury/src/serializer.rs
+++ /dev/null
@@ -1,365 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-//! Implement the serializer of internal types in fury protocol
-//!
-//! Serializeable type should implements the Serialize trait.
-//! This file include all the internal type implements which describe in fury 
protocol,
-//! But custom type which serializable is not here, custom type implement the 
Serialize trait via fury-derive.
-//! # Examples:
-//! ```
-//!
-//! use fury::Fury;
-//! #[derive(Fury)]
-//! #[tag("example.foo2")]
-//! struct Animal {
-//! category: String,
-//! }
-//!
-//! ```
-//! fury::Fury would expand the code and automatic implements the Serialize 
trait
-
-use super::buffer::Writer;
-use super::types::{config_flags, FuryMeta, Language, RefFlag, 
SIZE_OF_REF_AND_TYPE};
-use chrono::{NaiveDate, NaiveDateTime};
-use std::collections::{HashMap, HashSet};
-use std::mem;
-
-/// Convert a typed slice to a u8 slice.
-/// Usually used to convert a typed array like Vec to &[u8], which can be 
easily written to a buffer.
-fn to_u8_slice<T>(slice: &[T]) -> &[u8] {
-    let byte_len = std::mem::size_of_val(slice);
-    unsafe { std::slice::from_raw_parts(slice.as_ptr().cast::<u8>(), byte_len) 
}
-}
-
-/// Types that implement the Serialize trait can be serialized to Fury.
-///
-/// 1. Normal situation:
-///    The order of function calls is reserved_space -> serialize -> write.
-///     a. reserved_space is used to allocate the fixed memory space, which 
can avoid the cost of the memory check.
-///         However, dynamic types like strings should allocate the size 
separately before being written to the buffer.
-///     b. serialize is used to serialize the data into the buffer. The first 
step is to write the object head,
-///         which includes one byte reference flag and two byte type flag.
-///         The second step is to call the write function, which is used to 
write the Rust object.
-///     c. write is used to write the Rust object into the buffer.
-/// 2. Vec situation:
-///    If the object is in a Vec, the call order is reserved_space -> 
serialize -> write -> write_vec.
-///    The write_vec function is used to write the elements of the Vec. But 
why can't we just loop through the elements and write each element one by one?
-///    This is because Fury includes some primitive types like 
FuryPrimitiveBoolArray which do not include the head of the elements,
-///    but other Vecs do. So the write_vec function is necessary to handle the 
differences. Primitive arrays can overwrite the function.
-pub trait Serialize
-where
-    Self: Sized + FuryMeta,
-{
-    /// This function is invoked when the data is in a Vec.
-    ///
-    /// The default implementation invokes the serialize function, which 
includes the type head. Some types like primitive arrays can overwrite it.
-    /// Step 1: write the length of the Vec into the buffer.
-    /// Step 2: reserve the fixed size of all the elements.
-    /// Step 3: loop through the Vec and invoke the serialize function of each 
item.
-    fn write_vec(value: &[Self], serializer: &mut SerializerState) {
-        serializer.writer.var_int32(value.len() as i32);
-        serializer
-            .writer
-            .reserve((<Self as Serialize>::reserved_space() + 
SIZE_OF_REF_AND_TYPE) * value.len());
-        for item in value.iter() {
-            item.serialize(serializer);
-        }
-    }
-
-    /// The fixed memory size of the Type.
-    /// Avoid the memory check, which would hurt performance.
-    fn reserved_space() -> usize;
-
-    /// Write the data into the buffer.
-    fn write(&self, serializer: &mut SerializerState);
-
-    /// Entry point of the serialization.
-    ///
-    /// Step 1: write the type flag and type flag into the buffer.
-    /// Step 2: invoke the write function to write the Rust object.
-    fn serialize(&self, serializer: &mut SerializerState) {
-        // ref flag
-        serializer.writer.i8(RefFlag::NotNullValue as i8);
-        // type
-        serializer.writer.i16(if Self::is_vec() {
-            Self::vec_ty()
-        } else {
-            Self::ty()
-        } as i16);
-        self.write(serializer);
-    }
-}
-
-/// Implement Serialize for all the number types.
-///
-/// Serializing number types is similar, the only difference is the fixed size.
-macro_rules! impl_num_serialize {
-    ($name: ident, $ty:tt) => {
-        impl Serialize for $ty {
-            fn write(&self, serializer: &mut SerializerState) {
-                serializer.writer.$name(*self);
-            }
-
-            fn reserved_space() -> usize {
-                mem::size_of::<$ty>()
-            }
-        }
-    };
-}
-
-/// Implement Serialize for all the number types, but overwrite the primitive 
type Vec, which does not include the object head.
-macro_rules! impl_num_serialize_and_pritimive_vec {
-    ($name: ident, $ty:tt) => {
-        impl Serialize for $ty {
-            fn write(&self, serializer: &mut SerializerState) {
-                serializer.writer.$name(*self);
-            }
-
-            fn write_vec(value: &[Self], serializer: &mut SerializerState) {
-                serializer.writer.var_int32(value.len() as i32);
-                serializer.writer.bytes(to_u8_slice(value));
-            }
-
-            fn reserved_space() -> usize {
-                mem::size_of::<$ty>()
-            }
-        }
-    };
-}
-
-impl_num_serialize!(u16, u16);
-impl_num_serialize!(u32, u32);
-impl_num_serialize!(u64, u64);
-impl_num_serialize!(i8, i8);
-
-impl_num_serialize_and_pritimive_vec!(u8, u8);
-impl_num_serialize_and_pritimive_vec!(i16, i16);
-impl_num_serialize_and_pritimive_vec!(i32, i32);
-impl_num_serialize_and_pritimive_vec!(i64, i64);
-impl_num_serialize_and_pritimive_vec!(f32, f32);
-impl_num_serialize_and_pritimive_vec!(f64, f64);
-
-/// The implement of String Type
-impl Serialize for String {
-    fn write(&self, serializer: &mut SerializerState) {
-        serializer.writer.var_int32(self.len() as i32);
-        serializer.writer.bytes(self.as_bytes());
-    }
-
-    fn write_vec(value: &[Self], serializer: &mut SerializerState) {
-        serializer.writer.var_int32(value.len() as i32);
-        serializer
-            .writer
-            .reserve((<Self as Serialize>::reserved_space()) * value.len());
-
-        for x in value.iter() {
-            x.write(serializer);
-        }
-    }
-
-    fn reserved_space() -> usize {
-        mem::size_of::<i32>()
-    }
-}
-
-impl Serialize for bool {
-    fn write(&self, serializer: &mut SerializerState) {
-        serializer.writer.u8(if *self { 1 } else { 0 });
-    }
-
-    fn write_vec(value: &[Self], serializer: &mut SerializerState) {
-        serializer.writer.var_int32(value.len() as i32);
-        serializer.writer.bytes(to_u8_slice(value));
-    }
-
-    fn reserved_space() -> usize {
-        mem::size_of::<u8>()
-    }
-}
-
-impl<T1: Serialize, T2: Serialize> Serialize for HashMap<T1, T2> {
-    fn write(&self, serializer: &mut SerializerState) {
-        // length
-        serializer.writer.var_int32(self.len() as i32);
-
-        let reserved_space = (<T1 as Serialize>::reserved_space() + 
SIZE_OF_REF_AND_TYPE)
-            * self.len()
-            + (<T2 as Serialize>::reserved_space() + SIZE_OF_REF_AND_TYPE) * 
self.len();
-        serializer.writer.reserve(reserved_space);
-
-        // key-value
-        for i in self.iter() {
-            i.0.serialize(serializer);
-            i.1.serialize(serializer);
-        }
-    }
-
-    fn reserved_space() -> usize {
-        mem::size_of::<i32>()
-    }
-}
-
-impl<T: Serialize> Serialize for HashSet<T> {
-    fn write(&self, serializer: &mut SerializerState) {
-        // length
-        serializer.writer.i32(self.len() as i32);
-
-        let reserved_space =
-            (<T as Serialize>::reserved_space() + SIZE_OF_REF_AND_TYPE) * 
self.len();
-        serializer.writer.reserve(reserved_space);
-
-        // key-value
-        for i in self.iter() {
-            i.serialize(serializer);
-        }
-    }
-
-    fn reserved_space() -> usize {
-        mem::size_of::<i32>()
-    }
-}
-
-impl Serialize for NaiveDateTime {
-    fn write(&self, serializer: &mut SerializerState) {
-        serializer
-            .writer
-            .u64(self.and_utc().timestamp_millis() as u64);
-    }
-
-    fn reserved_space() -> usize {
-        mem::size_of::<u64>()
-    }
-}
-
-lazy_static::lazy_static!(
-    static ref EPOCH: NaiveDate = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap();
-);
-
-impl Serialize for NaiveDate {
-    fn write(&self, serializer: &mut SerializerState) {
-        let days_since_epoch = self.signed_duration_since(*EPOCH).num_days();
-        serializer.writer.u64(days_since_epoch as u64);
-    }
-
-    fn reserved_space() -> usize {
-        mem::size_of::<u64>()
-    }
-}
-
-impl<T> Serialize for Vec<T>
-where
-    T: Serialize,
-{
-    fn write(&self, serializer: &mut SerializerState) {
-        T::write_vec(self, serializer);
-    }
-
-    fn reserved_space() -> usize {
-        // size of the vec
-        mem::size_of::<u32>()
-    }
-}
-
-impl<T> Serialize for Option<T>
-where
-    T: Serialize,
-{
-    fn write(&self, serializer: &mut SerializerState) {
-        if let Some(v) = self {
-            T::write(v, serializer)
-        } else {
-            unreachable!("write should be call by serialize")
-        }
-    }
-
-    fn serialize(&self, serializer: &mut SerializerState) {
-        match self {
-            Some(v) => {
-                // ref flag
-                serializer.writer.i8(RefFlag::NotNullValue as i8);
-                // type
-                serializer.writer.i16(<Self as FuryMeta>::ty() as i16);
-
-                v.write(serializer);
-            }
-            None => {
-                serializer.writer.i8(RefFlag::Null as i8);
-            }
-        }
-    }
-
-    fn reserved_space() -> usize {
-        mem::size_of::<T>()
-    }
-}
-
-pub struct SerializerState<'se> {
-    pub writer: &'se mut Writer,
-    pub tags: Vec<&'static str>,
-}
-
-impl<'de> SerializerState<'de> {
-    fn new(writer: &mut Writer) -> SerializerState {
-        SerializerState {
-            writer,
-            tags: Vec::new(),
-        }
-    }
-
-    pub fn write_tag(&mut self, tag: &'static str) {
-        const USESTRINGVALUE: u8 = 0;
-        const USESTRINGID: u8 = 1;
-
-        let mayby_idx = self.tags.iter().position(|x| *x == tag);
-        match mayby_idx {
-            Some(idx) => {
-                self.writer.u8(USESTRINGID);
-                self.writer.i16(idx as i16);
-            }
-            None => {
-                self.writer.u8(USESTRINGVALUE);
-                self.writer.skip(8); // todo tag hash
-                self.writer.i16(tag.len() as i16);
-                self.writer.bytes(tag.as_bytes());
-            }
-        };
-    }
-
-    fn head<T: Serialize>(&mut self) -> &Self {
-        const HEAD_SIZE: usize = 10;
-        self.writer
-            .reserve(<T as Serialize>::reserved_space() + SIZE_OF_REF_AND_TYPE 
+ HEAD_SIZE);
-
-        let mut bitmap = 0;
-        bitmap |= config_flags::IS_LITTLE_ENDIAN_FLAG;
-        bitmap |= config_flags::IS_CROSS_LANGUAGE_FLAG;
-        self.writer.u8(bitmap);
-        self.writer.u8(Language::Rust as u8);
-        self.writer.skip(4); // native offset
-        self.writer.skip(4); // native size
-        self
-    }
-}
-
-pub fn to_buffer<T: Serialize>(record: &T) -> Vec<u8> {
-    let mut writer = Writer::default();
-    let mut serializer = SerializerState::new(&mut writer);
-    serializer.head::<T>();
-    <T as Serialize>::serialize(record, &mut serializer);
-    writer.dump()
-}
diff --git a/rust/tests/Cargo.toml b/rust/tests/Cargo.toml
index 340411c1..07a8afa7 100644
--- a/rust/tests/Cargo.toml
+++ b/rust/tests/Cargo.toml
@@ -23,7 +23,7 @@ rust-version.workspace = true
 publish = false
 
 [dependencies]
-fury = { path = "../fury" }
+fury-core = { path = "../fury-core" }
 fury-derive = { path = "../fury-derive" }
 
 chrono = "0.4"
diff --git a/rust/tests/tests/test_complex_struct.rs 
b/rust/tests/tests/test_complex_struct.rs
index b114db42..fddf5eb5 100644
--- a/rust/tests/tests/test_complex_struct.rs
+++ b/rust/tests/tests/test_complex_struct.rs
@@ -16,7 +16,8 @@
 // under the License.
 
 use chrono::{DateTime, NaiveDate, NaiveDateTime};
-use fury::{from_buffer, to_buffer, Fury};
+use fury_core::fury::Fury;
+use fury_derive::Fury;
 use std::collections::HashMap;
 
 #[test]
@@ -64,55 +65,12 @@ fn complex_struct() {
         c5: 2.0,
         c6: 4.0,
     };
-
-    let bin: Vec<u8> = to_buffer(&person);
-    let obj: Person = from_buffer(&bin).expect("should success");
+    let fury = Fury::default();
+    let bin: Vec<u8> = fury.serialize(&person);
+    let obj: Person = fury.deserialize(&bin).expect("should success");
     assert_eq!(person, obj);
 }
 
-#[test]
-fn decode_py_struct() {
-    #[derive(Fury, Debug, PartialEq)]
-    #[tag("example.foo2")]
-    struct Animal {
-        category: String,
-    }
-
-    #[derive(Fury, Debug, PartialEq)]
-    #[tag("example.ComplexObject")]
-    struct Person {
-        f1: String,
-        f2: HashMap<String, i8>,
-        f3: i8,
-        f4: i16,
-        f5: i32,
-        f6: i64,
-        f7: f32,
-        f8: f64,
-        f9: Vec<i16>,
-        f10: HashMap<i32, f64>,
-    }
-
-    let bin = [
-        134, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 81, 159, 160, 124, 69, 
240, 2, 120, 21, 0,
-        101, 120, 97, 109, 112, 108, 101, 46, 67, 111, 109, 112, 108, 101, 
120, 79, 98, 106, 101,
-        99, 116, 71, 168, 32, 21, 0, 13, 0, 3, 115, 116, 114, 0, 30, 0, 2, 
255, 7, 0, 1, 0, 0, 0,
-        255, 12, 0, 85, 85, 85, 85, 85, 85, 213, 63, 255, 7, 0, 100, 0, 0, 0, 
255, 12, 0, 146, 36,
-        73, 146, 36, 73, 210, 63, 0, 30, 0, 2, 0, 13, 0, 2, 107, 49, 255, 3, 
0, 255, 0, 13, 0, 2,
-        107, 50, 255, 3, 0, 2, 255, 3, 0, 127, 255, 5, 0, 255, 127, 255, 7, 0, 
255, 255, 255, 127,
-        255, 9, 0, 255, 255, 255, 255, 255, 255, 255, 127, 255, 11, 0, 0, 0, 
0, 63, 255, 12, 0, 85,
-        85, 85, 85, 85, 85, 229, 63, 0, 25, 0, 2, 255, 5, 0, 1, 0, 255, 5, 0, 
2, 0, 134, 2, 98, 0,
-        0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 81, 159, 160, 124, 69, 240, 2, 120, 21, 
0, 101, 120, 97, 109,
-        112, 108, 101, 46, 67, 111, 109, 112, 108, 101, 120, 79, 98, 106, 101, 
99, 116, 71, 168,
-        32, 21, 253, 253, 253, 255, 3, 0, 0, 255, 5, 0, 0, 0, 255, 7, 0, 0, 0, 
0, 0, 255, 9, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 255, 11, 0, 171, 170, 170, 62, 255, 12, 0, 0, 0, 
0, 0, 0, 0, 0, 0,
-        253,
-    ];
-
-    let obj: Person = from_buffer(&bin).expect("should some");
-    print!("{:?}", obj);
-}
-
 #[test]
 fn encode_to_obin() {
     #[derive(Fury, Debug, PartialEq)]
@@ -134,8 +92,8 @@ fn encode_to_obin() {
         f8: f64,
         f10: HashMap<i32, f64>,
     }
-
-    let bin: Vec<u8> = to_buffer(&Person {
+    let fury = Fury::default();
+    let bin: Vec<u8> = fury.serialize(&Person {
         f1: "Hello".to_string(),
         f2: HashMap::from([("hello1".to_string(), 1), ("hello2".to_string(), 
2)]),
         f3: 1,
diff --git a/rust/tests/tests/test_meta_string.rs 
b/rust/tests/tests/test_meta_string.rs
index a1065f39..d90f8a81 100644
--- a/rust/tests/tests/test_meta_string.rs
+++ b/rust/tests/tests/test_meta_string.rs
@@ -17,7 +17,7 @@
 
 use std::iter;
 
-use fury::{Encoding, MetaStringDecoder, MetaStringEncoder};
+use fury_core::meta::{Encoding, MetaStringDecoder, MetaStringEncoder};
 
 #[test]
 fn test_encode_meta_string_lower_special() {
diff --git a/rust/tests/tests/test_row.rs b/rust/tests/tests/test_row.rs
index c37ac01b..d5bce9c0 100644
--- a/rust/tests/tests/test_row.rs
+++ b/rust/tests/tests/test_row.rs
@@ -17,7 +17,8 @@
 
 use std::collections::BTreeMap;
 
-use fury::{from_row, to_row, FuryRow};
+use fury_core::row::{from_row, to_row};
+use fury_derive::FuryRow;
 
 #[test]
 fn row() {
diff --git a/rust/tests/tests/test_util.rs b/rust/tests/tests/test_util.rs
index a37705c9..85a71246 100644
--- a/rust/tests/tests/test_util.rs
+++ b/rust/tests/tests/test_util.rs
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use fury::to_utf8;
+use fury_core::util::to_utf8;
 
 #[test]
 fn test_to_utf8() {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to