From 7d76794d57fc7c18d36b58c950eae81873232081 Mon Sep 17 00:00:00 2001 From: "wangjie.wjdew" Date: Tue, 5 Nov 2024 18:09:08 +0800 Subject: [PATCH] fix(pilota-thrift-parser): compatible with separators after different item blocks in idl --- Cargo.lock | 2 +- pilota-build/test_data/thrift/separator.rs | 1001 +++++++++++++++++ .../test_data/thrift/separator.thrift | 20 + pilota-thrift-parser/Cargo.toml | 2 +- pilota-thrift-parser/src/parser/enum_.rs | 3 +- pilota-thrift-parser/src/parser/service.rs | 3 +- pilota-thrift-parser/src/parser/struct_.rs | 3 +- pilota-thrift-parser/src/parser/typedef.rs | 3 +- 8 files changed, 1030 insertions(+), 7 deletions(-) create mode 100644 pilota-build/test_data/thrift/separator.rs create mode 100644 pilota-build/test_data/thrift/separator.thrift diff --git a/Cargo.lock b/Cargo.lock index 4a7cbab4..21c94c99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -884,7 +884,7 @@ dependencies = [ [[package]] name = "pilota-thrift-parser" -version = "0.11.3" +version = "0.11.4" dependencies = [ "nom", ] diff --git a/pilota-build/test_data/thrift/separator.rs b/pilota-build/test_data/thrift/separator.rs new file mode 100644 index 00000000..e482d8f6 --- /dev/null +++ b/pilota-build/test_data/thrift/separator.rs @@ -0,0 +1,1001 @@ +pub mod seperator { + #![allow(warnings, clippy::all)] + + pub mod seperator { + #[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] + pub struct MyInt32(pub i32); + + impl ::std::ops::Deref for MyInt32 { + type Target = i32; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl From for MyInt32 { + fn from(v: i32) -> Self { + Self(v) + } + } + + impl ::pilota::thrift::Message for MyInt32 { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + __protocol.write_i32(*(&**self))?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + ::std::result::Result::Ok(MyInt32(__protocol.read_i32()?)) + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + ::std::result::Result::Ok(MyInt32(__protocol.read_i32().await?)) + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.i32_len(*&**self) + } + } + pub trait Service {} + #[derive(PartialOrd, Hash, Eq, Ord, Debug, ::pilota::derivative::Derivative)] + #[derivative(Default)] + #[derive(Clone, PartialEq)] + pub enum ServiceTestEpisodeResultRecv { + #[derivative(Default)] + Ok(MyStruct), + } + + impl ::pilota::thrift::Message for ServiceTestEpisodeResultRecv { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + __protocol.write_struct_begin(&::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeResultRecv", + })?; + match self { + ServiceTestEpisodeResultRecv::Ok(ref value) => { + __protocol.write_struct_field(0, value, ::pilota::thrift::TType::Struct)?; + } + } + __protocol.write_field_stop()?; + __protocol.write_struct_end()?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + let mut ret = None; + __protocol.read_struct_begin()?; + loop { + let field_ident = __protocol.read_field_begin()?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + __protocol.field_stop_len(); + break; + } else { + __protocol.field_begin_len(field_ident.field_type, field_ident.id); + } + match field_ident.id { + Some(0) => { + if ret.is_none() { + let field_ident = ::pilota::thrift::Message::decode(__protocol)?; + __protocol.struct_len(&field_ident); + ret = Some(ServiceTestEpisodeResultRecv::Ok(field_ident)); + } else { + return ::std::result::Result::Err( + ::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received multiple fields for union from remote Message", + ), + ); + } + } + _ => { + __protocol.skip(field_ident.field_type)?; + } + } + } + __protocol.read_field_end()?; + __protocol.read_struct_end()?; + if let Some(ret) = ret { + ::std::result::Result::Ok(ret) + } else { + ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received empty union from remote Message", + )) + } + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + let mut ret = None; + __protocol.read_struct_begin().await?; + loop { + let field_ident = __protocol.read_field_begin().await?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + break; + } else { + } + match field_ident.id { + Some(0) => { + if ret.is_none() { + let field_ident = + ::decode_async( + __protocol, + ) + .await?; + + ret = Some(ServiceTestEpisodeResultRecv::Ok(field_ident)); + } else { + return ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received multiple fields for union from remote Message" + )); + } + } + _ => { + __protocol.skip(field_ident.field_type).await?; + } + } + } + __protocol.read_field_end().await?; + __protocol.read_struct_end().await?; + if let Some(ret) = ret { + ::std::result::Result::Ok(ret) + } else { + ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received empty union from remote Message", + )) + } + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.struct_begin_len(&::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeResultRecv", + }) + match self { + ServiceTestEpisodeResultRecv::Ok(ref value) => { + __protocol.struct_field_len(Some(0), value) + } + } + __protocol.field_stop_len() + + __protocol.struct_end_len() + } + } + #[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] + pub struct TypedefTestStruct { + pub field_my_int32: ::std::option::Option, + + pub field_my_string: ::std::option::Option, + + pub field_int32: ::std::option::Option, + + pub field_string: ::std::option::Option<::pilota::FastStr>, + } + impl ::pilota::thrift::Message for TypedefTestStruct { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + let struct_ident = ::pilota::thrift::TStructIdentifier { + name: "TypedefTestStruct", + }; + + __protocol.write_struct_begin(&struct_ident)?; + if let Some(value) = self.field_my_int32.as_ref() { + __protocol.write_struct_field(1, value, ::pilota::thrift::TType::I32)?; + } + if let Some(value) = self.field_my_string.as_ref() { + __protocol.write_struct_field(2, value, ::pilota::thrift::TType::Binary)?; + } + if let Some(value) = self.field_int32.as_ref() { + __protocol.write_i32_field(3, *value)?; + } + if let Some(value) = self.field_string.as_ref() { + __protocol.write_faststr_field(4, (value).clone())?; + } + __protocol.write_field_stop()?; + __protocol.write_struct_end()?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + + let mut var_1 = None; + let mut var_2 = None; + let mut var_3 = None; + let mut var_4 = None; + + let mut __pilota_decoding_field_id = None; + + __protocol.read_struct_begin()?; + if let ::std::result::Result::Err(mut err) = (|| { + loop { + let field_ident = __protocol.read_field_begin()?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + __protocol.field_stop_len(); + break; + } else { + __protocol.field_begin_len(field_ident.field_type, field_ident.id); + } + __pilota_decoding_field_id = field_ident.id; + match field_ident.id { + Some(1) if field_ident.field_type == ::pilota::thrift::TType::I32 => { + var_1 = Some(::pilota::thrift::Message::decode(__protocol)?); + } + Some(2) + if field_ident.field_type == ::pilota::thrift::TType::Binary => + { + var_2 = Some(::pilota::thrift::Message::decode(__protocol)?); + } + Some(3) if field_ident.field_type == ::pilota::thrift::TType::I32 => { + var_3 = Some(__protocol.read_i32()?); + } + Some(4) + if field_ident.field_type == ::pilota::thrift::TType::Binary => + { + var_4 = Some(__protocol.read_faststr()?); + } + _ => { + __protocol.skip(field_ident.field_type)?; + } + } + + __protocol.read_field_end()?; + __protocol.field_end_len(); + } + ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) + })() { + if let Some(field_id) = __pilota_decoding_field_id { + err.prepend_msg(&format!( + "decode struct `TypedefTestStruct` field(#{}) failed, caused by: ", + field_id + )); + } + return ::std::result::Result::Err(err); + }; + __protocol.read_struct_end()?; + + let data = Self { + field_my_int32: var_1, + field_my_string: var_2, + field_int32: var_3, + field_string: var_4, + }; + ::std::result::Result::Ok(data) + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + let mut var_1 = None; + let mut var_2 = None; + let mut var_3 = None; + let mut var_4 = None; + + let mut __pilota_decoding_field_id = None; + + __protocol.read_struct_begin().await?; + if let ::std::result::Result::Err(mut err) = async { + loop { + let field_ident = __protocol.read_field_begin().await?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + break; + } else { + } + __pilota_decoding_field_id = field_ident.id; + match field_ident.id { + Some(1) + if field_ident.field_type == ::pilota::thrift::TType::I32 => + { + var_1 = Some( + ::decode_async( + __protocol, + ) + .await?, + ); + } + Some(2) + if field_ident.field_type + == ::pilota::thrift::TType::Binary => + { + var_2 = Some( + ::decode_async( + __protocol, + ) + .await?, + ); + } + Some(3) + if field_ident.field_type == ::pilota::thrift::TType::I32 => + { + var_3 = Some(__protocol.read_i32().await?); + } + Some(4) + if field_ident.field_type + == ::pilota::thrift::TType::Binary => + { + var_4 = Some(__protocol.read_faststr().await?); + } + _ => { + __protocol.skip(field_ident.field_type).await?; + } + } + + __protocol.read_field_end().await?; + } + ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) + } + .await + { + if let Some(field_id) = __pilota_decoding_field_id { + err.prepend_msg(&format!( + "decode struct `TypedefTestStruct` field(#{}) failed, caused by: ", + field_id + )); + } + return ::std::result::Result::Err(err); + }; + __protocol.read_struct_end().await?; + + let data = Self { + field_my_int32: var_1, + field_my_string: var_2, + field_int32: var_3, + field_string: var_4, + }; + ::std::result::Result::Ok(data) + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.struct_begin_len(&::pilota::thrift::TStructIdentifier { + name: "TypedefTestStruct", + }) + self + .field_my_int32 + .as_ref() + .map_or(0, |value| __protocol.struct_field_len(Some(1), value)) + + self + .field_my_string + .as_ref() + .map_or(0, |value| __protocol.struct_field_len(Some(2), value)) + + self + .field_int32 + .as_ref() + .map_or(0, |value| __protocol.i32_field_len(Some(3), *value)) + + self + .field_string + .as_ref() + .map_or(0, |value| __protocol.faststr_field_len(Some(4), value)) + + __protocol.field_stop_len() + + __protocol.struct_end_len() + } + } + #[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] + pub struct ServiceTestEpisodeArgsRecv { + pub arg: MyStruct, + } + impl ::pilota::thrift::Message for ServiceTestEpisodeArgsRecv { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + let struct_ident = ::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeArgsRecv", + }; + + __protocol.write_struct_begin(&struct_ident)?; + __protocol.write_struct_field(1, &self.arg, ::pilota::thrift::TType::Struct)?; + __protocol.write_field_stop()?; + __protocol.write_struct_end()?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + + let mut var_1 = None; + + let mut __pilota_decoding_field_id = None; + + __protocol.read_struct_begin()?; + if let ::std::result::Result::Err(mut err) = (|| { + loop { + let field_ident = __protocol.read_field_begin()?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + __protocol.field_stop_len(); + break; + } else { + __protocol.field_begin_len(field_ident.field_type, field_ident.id); + } + __pilota_decoding_field_id = field_ident.id; + match field_ident.id { + Some(1) + if field_ident.field_type == ::pilota::thrift::TType::Struct => + { + var_1 = Some(::pilota::thrift::Message::decode(__protocol)?); + } + _ => { + __protocol.skip(field_ident.field_type)?; + } + } + + __protocol.read_field_end()?; + __protocol.field_end_len(); + } + ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) + })() { + if let Some(field_id) = __pilota_decoding_field_id { + err.prepend_msg(&format!("decode struct `ServiceTestEpisodeArgsRecv` field(#{}) failed, caused by: ", field_id)); + } + return ::std::result::Result::Err(err); + }; + __protocol.read_struct_end()?; + + let Some(var_1) = var_1 else { + return ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "field arg is required".to_string(), + )); + }; + + let data = Self { arg: var_1 }; + ::std::result::Result::Ok(data) + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + let mut var_1 = None; + + let mut __pilota_decoding_field_id = None; + + __protocol.read_struct_begin().await?; + if let ::std::result::Result::Err(mut err) = async { + loop { + let field_ident = __protocol.read_field_begin().await?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + break; + } else { + } + __pilota_decoding_field_id = field_ident.id; + match field_ident.id { + Some(1) + if field_ident.field_type + == ::pilota::thrift::TType::Struct => + { + var_1 = Some( + ::decode_async( + __protocol, + ) + .await?, + ); + } + _ => { + __protocol.skip(field_ident.field_type).await?; + } + } + + __protocol.read_field_end().await?; + } + ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) + } + .await + { + if let Some(field_id) = __pilota_decoding_field_id { + err.prepend_msg(&format!("decode struct `ServiceTestEpisodeArgsRecv` field(#{}) failed, caused by: ", field_id)); + } + return ::std::result::Result::Err(err); + }; + __protocol.read_struct_end().await?; + + let Some(var_1) = var_1 else { + return ::std::result::Result::Err( + ::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "field arg is required".to_string(), + ), + ); + }; + + let data = Self { arg: var_1 }; + ::std::result::Result::Ok(data) + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.struct_begin_len(&::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeArgsRecv", + }) + __protocol.struct_field_len(Some(1), &self.arg) + + __protocol.field_stop_len() + + __protocol.struct_end_len() + } + } + #[derive(PartialOrd, Hash, Eq, Ord, Debug, ::pilota::derivative::Derivative)] + #[derivative(Default)] + #[derive(Clone, PartialEq)] + pub enum ServiceTestEpisodeResultSend { + #[derivative(Default)] + Ok(MyStruct), + } + + impl ::pilota::thrift::Message for ServiceTestEpisodeResultSend { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + __protocol.write_struct_begin(&::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeResultSend", + })?; + match self { + ServiceTestEpisodeResultSend::Ok(ref value) => { + __protocol.write_struct_field(0, value, ::pilota::thrift::TType::Struct)?; + } + } + __protocol.write_field_stop()?; + __protocol.write_struct_end()?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + let mut ret = None; + __protocol.read_struct_begin()?; + loop { + let field_ident = __protocol.read_field_begin()?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + __protocol.field_stop_len(); + break; + } else { + __protocol.field_begin_len(field_ident.field_type, field_ident.id); + } + match field_ident.id { + Some(0) => { + if ret.is_none() { + let field_ident = ::pilota::thrift::Message::decode(__protocol)?; + __protocol.struct_len(&field_ident); + ret = Some(ServiceTestEpisodeResultSend::Ok(field_ident)); + } else { + return ::std::result::Result::Err( + ::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received multiple fields for union from remote Message", + ), + ); + } + } + _ => { + __protocol.skip(field_ident.field_type)?; + } + } + } + __protocol.read_field_end()?; + __protocol.read_struct_end()?; + if let Some(ret) = ret { + ::std::result::Result::Ok(ret) + } else { + ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received empty union from remote Message", + )) + } + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + let mut ret = None; + __protocol.read_struct_begin().await?; + loop { + let field_ident = __protocol.read_field_begin().await?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + break; + } else { + } + match field_ident.id { + Some(0) => { + if ret.is_none() { + let field_ident = + ::decode_async( + __protocol, + ) + .await?; + + ret = Some(ServiceTestEpisodeResultSend::Ok(field_ident)); + } else { + return ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received multiple fields for union from remote Message" + )); + } + } + _ => { + __protocol.skip(field_ident.field_type).await?; + } + } + } + __protocol.read_field_end().await?; + __protocol.read_struct_end().await?; + if let Some(ret) = ret { + ::std::result::Result::Ok(ret) + } else { + ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "received empty union from remote Message", + )) + } + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.struct_begin_len(&::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeResultSend", + }) + match self { + ServiceTestEpisodeResultSend::Ok(ref value) => { + __protocol.struct_field_len(Some(0), value) + } + } + __protocol.field_stop_len() + + __protocol.struct_end_len() + } + } + pub const TEST_LIST: [&'static str; 2] = ["hello", "world"]; + #[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] + pub struct MyString(pub ::pilota::FastStr); + + impl ::std::ops::Deref for MyString { + type Target = ::pilota::FastStr; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl From<::pilota::FastStr> for MyString { + fn from(v: ::pilota::FastStr) -> Self { + Self(v) + } + } + + impl ::pilota::thrift::Message for MyString { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + __protocol.write_faststr((&**self).clone())?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + ::std::result::Result::Ok(MyString(__protocol.read_faststr()?)) + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + ::std::result::Result::Ok(MyString(__protocol.read_faststr().await?)) + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.faststr_len(&**self) + } + } + #[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] + pub struct ServiceTestEpisodeArgsSend { + pub arg: MyStruct, + } + impl ::pilota::thrift::Message for ServiceTestEpisodeArgsSend { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + let struct_ident = ::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeArgsSend", + }; + + __protocol.write_struct_begin(&struct_ident)?; + __protocol.write_struct_field(1, &self.arg, ::pilota::thrift::TType::Struct)?; + __protocol.write_field_stop()?; + __protocol.write_struct_end()?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + + let mut var_1 = None; + + let mut __pilota_decoding_field_id = None; + + __protocol.read_struct_begin()?; + if let ::std::result::Result::Err(mut err) = (|| { + loop { + let field_ident = __protocol.read_field_begin()?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + __protocol.field_stop_len(); + break; + } else { + __protocol.field_begin_len(field_ident.field_type, field_ident.id); + } + __pilota_decoding_field_id = field_ident.id; + match field_ident.id { + Some(1) + if field_ident.field_type == ::pilota::thrift::TType::Struct => + { + var_1 = Some(::pilota::thrift::Message::decode(__protocol)?); + } + _ => { + __protocol.skip(field_ident.field_type)?; + } + } + + __protocol.read_field_end()?; + __protocol.field_end_len(); + } + ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) + })() { + if let Some(field_id) = __pilota_decoding_field_id { + err.prepend_msg(&format!("decode struct `ServiceTestEpisodeArgsSend` field(#{}) failed, caused by: ", field_id)); + } + return ::std::result::Result::Err(err); + }; + __protocol.read_struct_end()?; + + let Some(var_1) = var_1 else { + return ::std::result::Result::Err(::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "field arg is required".to_string(), + )); + }; + + let data = Self { arg: var_1 }; + ::std::result::Result::Ok(data) + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + let mut var_1 = None; + + let mut __pilota_decoding_field_id = None; + + __protocol.read_struct_begin().await?; + if let ::std::result::Result::Err(mut err) = async { + loop { + let field_ident = __protocol.read_field_begin().await?; + if field_ident.field_type == ::pilota::thrift::TType::Stop { + break; + } else { + } + __pilota_decoding_field_id = field_ident.id; + match field_ident.id { + Some(1) + if field_ident.field_type + == ::pilota::thrift::TType::Struct => + { + var_1 = Some( + ::decode_async( + __protocol, + ) + .await?, + ); + } + _ => { + __protocol.skip(field_ident.field_type).await?; + } + } + + __protocol.read_field_end().await?; + } + ::std::result::Result::Ok::<_, ::pilota::thrift::ThriftException>(()) + } + .await + { + if let Some(field_id) = __pilota_decoding_field_id { + err.prepend_msg(&format!("decode struct `ServiceTestEpisodeArgsSend` field(#{}) failed, caused by: ", field_id)); + } + return ::std::result::Result::Err(err); + }; + __protocol.read_struct_end().await?; + + let Some(var_1) = var_1 else { + return ::std::result::Result::Err( + ::pilota::thrift::new_protocol_exception( + ::pilota::thrift::ProtocolExceptionKind::InvalidData, + "field arg is required".to_string(), + ), + ); + }; + + let data = Self { arg: var_1 }; + ::std::result::Result::Ok(data) + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.struct_begin_len(&::pilota::thrift::TStructIdentifier { + name: "ServiceTestEpisodeArgsSend", + }) + __protocol.struct_field_len(Some(1), &self.arg) + + __protocol.field_stop_len() + + __protocol.struct_end_len() + } + } + #[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)] + pub struct MyStruct(pub TypedefTestStruct); + + impl ::std::ops::Deref for MyStruct { + type Target = TypedefTestStruct; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl From for MyStruct { + fn from(v: TypedefTestStruct) -> Self { + Self(v) + } + } + + impl ::pilota::thrift::Message for MyStruct { + fn encode( + &self, + __protocol: &mut T, + ) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> { + #[allow(unused_imports)] + use ::pilota::thrift::TOutputProtocolExt; + __protocol.write_struct((&**self))?; + ::std::result::Result::Ok(()) + } + + fn decode( + __protocol: &mut T, + ) -> ::std::result::Result { + #[allow(unused_imports)] + use ::pilota::{thrift::TLengthProtocolExt, Buf}; + ::std::result::Result::Ok(MyStruct(::pilota::thrift::Message::decode(__protocol)?)) + } + + fn decode_async<'a, T: ::pilota::thrift::TAsyncInputProtocol>( + __protocol: &'a mut T, + ) -> ::std::pin::Pin< + ::std::boxed::Box< + dyn ::std::future::Future< + Output = ::std::result::Result, + > + Send + + 'a, + >, + > { + ::std::boxed::Box::pin(async move { + ::std::result::Result::Ok(MyStruct( + ::decode_async(__protocol) + .await?, + )) + }) + } + + fn size(&self, __protocol: &mut T) -> usize { + #[allow(unused_imports)] + use ::pilota::thrift::TLengthProtocolExt; + __protocol.struct_len(&**self) + } + } + } +} diff --git a/pilota-build/test_data/thrift/separator.thrift b/pilota-build/test_data/thrift/separator.thrift new file mode 100644 index 00000000..e3a0c06c --- /dev/null +++ b/pilota-build/test_data/thrift/separator.thrift @@ -0,0 +1,20 @@ +typedef i32 MyInt32 +typedef string MyString; + +struct TypedefTestStruct { + 1: MyInt32 field_MyInt32; + 2: MyString field_MyString; + 3: i32 field_Int32; + 4: string field_String; +}; + +typedef TypedefTestStruct MyStruct, + +const list TEST_LIST = [ + "hello", + "world", +]; + +service Service { + MyStruct testEpisode(1:MyStruct arg) +}, \ No newline at end of file diff --git a/pilota-thrift-parser/Cargo.toml b/pilota-thrift-parser/Cargo.toml index 6d883452..2fde13b4 100644 --- a/pilota-thrift-parser/Cargo.toml +++ b/pilota-thrift-parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pilota-thrift-parser" -version = "0.11.3" +version = "0.11.4" edition = "2021" description = "Pilota thrift Parser." documentation = "https://docs.rs/pilota" diff --git a/pilota-thrift-parser/src/parser/enum_.rs b/pilota-thrift-parser/src/parser/enum_.rs index 1a20a90d..ee82fdfe 100644 --- a/pilota-thrift-parser/src/parser/enum_.rs +++ b/pilota-thrift-parser/src/parser/enum_.rs @@ -23,9 +23,8 @@ impl Parser for EnumValue { opt(blank), opt(Annotations::parse), opt(list_separator), - opt(blank), )), - |(name, _, value, _, annotations, _, _)| EnumValue { + |(name, _, value, _, annotations, _)| EnumValue { name, value, annotations: annotations.unwrap_or_default(), diff --git a/pilota-thrift-parser/src/parser/service.rs b/pilota-thrift-parser/src/parser/service.rs index 9550e924..9bc26a96 100644 --- a/pilota-thrift-parser/src/parser/service.rs +++ b/pilota-thrift-parser/src/parser/service.rs @@ -28,8 +28,9 @@ impl Parser for Service { tag("}"), opt(blank), opt(Annotations::parse), + opt(list_separator), )), - |(_, _, name, extends, _, _, functions, _, _, _, annotations)| Service { + |(_, _, name, extends, _, _, functions, _, _, _, annotations, _)| Service { name, extends, functions, diff --git a/pilota-thrift-parser/src/parser/struct_.rs b/pilota-thrift-parser/src/parser/struct_.rs index ca13ec21..9a8e3101 100644 --- a/pilota-thrift-parser/src/parser/struct_.rs +++ b/pilota-thrift-parser/src/parser/struct_.rs @@ -50,8 +50,9 @@ impl Parser for StructLike { tag("}"), opt(blank), opt(Annotations::parse), + opt(list_separator), )), - |(name, _, _, fields, _, _, _, annotations)| StructLike { + |(name, _, _, fields, _, _, _, annotations, _)| StructLike { name, fields, annotations: annotations.unwrap_or_default(), diff --git a/pilota-thrift-parser/src/parser/typedef.rs b/pilota-thrift-parser/src/parser/typedef.rs index b19d6bcd..32e20b6a 100644 --- a/pilota-thrift-parser/src/parser/typedef.rs +++ b/pilota-thrift-parser/src/parser/typedef.rs @@ -21,8 +21,9 @@ impl Parser for Typedef { Ident::parse, opt(blank), opt(Annotations::parse), + opt(list_separator), )), - |(_, _, r#type, _, alias, _, annotations)| Typedef { + |(_, _, r#type, _, alias, _, annotations, _)| Typedef { r#type, alias, annotations: annotations.unwrap_or_default(),