Skip to content

Commit

Permalink
fix: use LazyLock for const type with nonconst construction
Browse files Browse the repository at this point in the history
  • Loading branch information
Millione committed Oct 8, 2024
1 parent c50d2bc commit 045f101
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 118 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pilota-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pilota-build"
version = "0.11.20"
version = "0.11.21"
edition = "2021"
description = "Compile thrift and protobuf idl into rust code at compile-time."
documentation = "https://docs.rs/pilota-build"
Expand Down
20 changes: 15 additions & 5 deletions pilota-build/src/middle/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,8 @@ impl Context {
v = format!("Some({v})").into()
}
anyhow::Ok((format!("{name}: {v}"), is_const))
} else if f.is_optional() {
anyhow::Ok((format!("{name}: None"), true))
} else {
anyhow::Ok((format!("{name}: Default::default()"), false))
}
Expand Down Expand Up @@ -770,13 +772,21 @@ impl Context {
Ok(if should_lazy_static {
let lit = self.lit_as_rvalue(lit, ty)?.0;
format! {r#"
::pilota::lazy_static::lazy_static! {{
pub static ref {name}: {ty} = {lit};
}}
pub static {name}: ::std::sync::LazyLock<{ty}> = ::std::sync::LazyLock::new(|| {{
{lit}
}});
"#}
} else {
let lit = self.lit_into_ty(lit, ty)?.0;
format!(r#"pub const {name}: {ty} = {lit};"#)
let (lit, is_const) = self.lit_into_ty(lit, ty)?;
if is_const {
format!(r#"pub const {name}: {ty} = {lit};"#)
} else {
format! {r#"
pub static {name}: ::std::sync::LazyLock<{ty}> = ::std::sync::LazyLock::new(|| {{
{lit}
}});
"#}
}
})
}

Expand Down
77 changes: 15 additions & 62 deletions pilota-build/src/symbol.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{fmt::Display, ops::Deref, sync::OnceLock};
use std::{
fmt::Display,
ops::Deref,
sync::{LazyLock, OnceLock},
};

use faststr::FastStr;
use heck::{ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase};
Expand All @@ -14,67 +18,16 @@ crate::newtype_index! {

pub static SPECIAL_NAMINGS: OnceLock<Vec<FastStr>> = OnceLock::new();

lazy_static::lazy_static! {
static ref KEYWORDS_SET: phf::Set<&'static str> = phf_set![
"as",
"use",
"break",
"const",
"continue",
"crate",
"else",
"if",
"enum",
"extern",
"false",
"fn",
"for",
"impl",
"in",
"let",
"loop",
"match",
"mod",
"move",
"mut",
"pub",
"ref",
"return",
"Self",
"self",
"static",
"struct",
"super",
"trait",
"true",
"type",
"unsafe",
"where",
"while",
"abstract",
"alignof",
"become",
"box",
"do",
"final",
"macro",
"offsetof",
"override",
"priv",
"proc",
"pure",
"sizeof",
"typeof",
"unsized",
"virtual",
"yield",
"dyn",
"async",
"await",
"try"
];

}
static KEYWORDS_SET: LazyLock<phf::Set<&'static str>> = LazyLock::new(|| {
phf_set![
"as", "use", "break", "const", "continue", "crate", "else", "if", "enum", "extern",
"false", "fn", "for", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub",
"ref", "return", "Self", "self", "static", "struct", "super", "trait", "true", "type",
"unsafe", "where", "while", "abstract", "alignof", "become", "box", "do", "final", "macro",
"offsetof", "override", "priv", "proc", "pure", "sizeof", "typeof", "unsized", "virtual",
"yield", "dyn", "async", "await", "try"
]
});

#[derive(Hash, PartialEq, Eq, Clone, Debug, PartialOrd, Ord)]
pub struct Symbol(pub FastStr);
Expand Down
203 changes: 193 additions & 10 deletions pilota-build/test_data/thrift/const_val.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,203 @@ pub mod const_val {
__protocol.i32_len(self.inner())
}
}
::pilota::lazy_static::lazy_static! {
pub static ref TEST_MAP_LIST: ::pilota::AHashMap<i32, ::std::vec::Vec<&'static str>> = {
pub const TEST_STRUCT: Test = Test { name: None };
pub static TEST_MAP: ::std::sync::LazyLock<::pilota::AHashMap<Index, &'static str>> =
::std::sync::LazyLock::new(|| {
let mut map = ::pilota::AHashMap::with_capacity(2);
map.insert(Index::A, "hello");
map.insert(Index::B, "world");
map
});
pub const TEST_LIST: [&'static str; 2] = ["hello", "world"];
pub static TEST_MAP_LIST: ::std::sync::LazyLock<
::pilota::AHashMap<i32, ::std::vec::Vec<&'static str>>,
> = ::std::sync::LazyLock::new(|| {
let mut map = ::pilota::AHashMap::with_capacity(1);
map.insert(1i32, ::std::vec!["hello"]);
map
};
});
#[derive(Debug, Default, Clone, PartialEq)]
pub struct Test {
pub name:
::std::option::Option<::pilota::AHashMap<::pilota::FastStr, ::pilota::FastStr>>,
}
pub const TEST_LIST: [&'static str; 2] = ["hello", "world"];
::pilota::lazy_static::lazy_static! {
pub static ref TEST_MAP: ::pilota::AHashMap<Index, &'static str> = {
let mut map = ::pilota::AHashMap::with_capacity(2);
map.insert(Index::A, "hello");map.insert(Index::B, "world");
map
};
impl ::pilota::thrift::Message for Test {
fn encode<T: ::pilota::thrift::TOutputProtocol>(
&self,
__protocol: &mut T,
) -> ::std::result::Result<(), ::pilota::thrift::ThriftException> {
#[allow(unused_imports)]
use ::pilota::thrift::TOutputProtocolExt;
let struct_ident = ::pilota::thrift::TStructIdentifier { name: "Test" };

__protocol.write_struct_begin(&struct_ident)?;
if let Some(value) = self.name.as_ref() {
__protocol.write_map_field(
1,
::pilota::thrift::TType::Binary,
::pilota::thrift::TType::Binary,
&value,
|__protocol, key| {
__protocol.write_faststr((key).clone())?;
::std::result::Result::Ok(())
},
|__protocol, val| {
__protocol.write_faststr((val).clone())?;
::std::result::Result::Ok(())
},
)?;
}
__protocol.write_field_stop()?;
__protocol.write_struct_end()?;
::std::result::Result::Ok(())
}

fn decode<T: ::pilota::thrift::TInputProtocol>(
__protocol: &mut T,
) -> ::std::result::Result<Self, ::pilota::thrift::ThriftException> {
#[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::Map => {
var_1 = Some({
let map_ident = __protocol.read_map_begin()?;
let mut val = ::pilota::AHashMap::with_capacity(map_ident.size);
for _ in 0..map_ident.size {
val.insert(
__protocol.read_faststr()?,
__protocol.read_faststr()?,
);
}
__protocol.read_map_end()?;
val
});
}
_ => {
__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 `Test` field(#{}) failed, caused by: ",
field_id
));
}
return ::std::result::Result::Err(err);
};
__protocol.read_struct_end()?;

let data = Self { name: 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<Self, ::pilota::thrift::ThriftException>,
> + 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::Map =>
{
var_1 = Some({
let map_ident = __protocol.read_map_begin().await?;
let mut val =
::pilota::AHashMap::with_capacity(map_ident.size);
for _ in 0..map_ident.size {
val.insert(
__protocol.read_faststr().await?,
__protocol.read_faststr().await?,
);
}
__protocol.read_map_end().await?;
val
});
}
_ => {
__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 `Test` field(#{}) failed, caused by: ",
field_id
));
}
return ::std::result::Result::Err(err);
};
__protocol.read_struct_end().await?;

let data = Self { name: var_1 };
::std::result::Result::Ok(data)
})
}

fn size<T: ::pilota::thrift::TLengthProtocol>(&self, __protocol: &mut T) -> usize {
#[allow(unused_imports)]
use ::pilota::thrift::TLengthProtocolExt;
__protocol.struct_begin_len(&::pilota::thrift::TStructIdentifier { name: "Test" })
+ self.name.as_ref().map_or(0, |value| {
__protocol.map_field_len(
Some(1),
::pilota::thrift::TType::Binary,
::pilota::thrift::TType::Binary,
value,
|__protocol, key| __protocol.faststr_len(key),
|__protocol, val| __protocol.faststr_len(val),
)
})
+ __protocol.field_stop_len()
+ __protocol.struct_end_len()
}
}
}
}
7 changes: 7 additions & 0 deletions pilota-build/test_data/thrift/const_val.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ enum Index {
B = 1,
}

struct Test {
1: map<string, string> name,
}

const map<Index, string> TEST_MAP = {
Index.A: "hello",
Index.B: "world",
Expand All @@ -17,4 +21,7 @@ const list<string> TEST_LIST = [

const map<i32, list<string>> TEST_MAP_LIST = {
1: ["hello"]
}

const Test TEST_STRUCT = {
}
14 changes: 7 additions & 7 deletions pilota-build/test_data/thrift/enum_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ pub mod enum_map {
pub const TYPE_B2: TypeB = TypeB(2i32);
pub const TYPE_A1: TypeA = TypeA(::pilota::FastStr::from_static_str("a1"));
pub const TYPE_B1: TypeB = TypeB(1i32);
::pilota::lazy_static::lazy_static! {
pub static ref TYPE_A_MAP: ::pilota::AHashMap<TypeB, TypeA> = {
let mut map = ::pilota::AHashMap::with_capacity(2);
map.insert(TYPE_B1, TYPE_A1);map.insert(TYPE_B2, TYPE_A2);
map
};
}
pub static TYPE_A_MAP: ::std::sync::LazyLock<::pilota::AHashMap<TypeB, TypeA>> =
::std::sync::LazyLock::new(|| {
let mut map = ::pilota::AHashMap::with_capacity(2);
map.insert(TYPE_B1, TYPE_A1);
map.insert(TYPE_B2, TYPE_A2);
map
});
#[derive(PartialOrd, Hash, Eq, Ord, Debug, Default, Clone, PartialEq)]
pub struct TypeA(pub ::pilota::FastStr);

Expand Down
Loading

0 comments on commit 045f101

Please sign in to comment.