Skip to content

Commit 8c4a1a5

Browse files
committed
idl: Support NonZero<num> in IDL
1 parent 1ebbe58 commit 8c4a1a5

File tree

5 files changed

+35
-0
lines changed

5 files changed

+35
-0
lines changed

cli/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2899,6 +2899,9 @@ fn deserialize_idl_type_to_json(
28992899
deserialize_idl_type_to_json(ty, data, parent_idl)?
29002900
}
29012901
}
2902+
IdlType::NonZero(ty) => {
2903+
deserialize_idl_type_to_json(ty, data, parent_idl)?
2904+
}
29022905
IdlType::Vec(ty) => {
29032906
let size: usize = <u32 as AnchorDeserialize>::deserialize(data)?
29042907
.try_into()

idl/spec/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ pub enum IdlType {
306306
#[serde(default, skip_serializing_if = "is_default")]
307307
generics: Vec<IdlGenericArg>,
308308
},
309+
NonZero(Box<IdlType>),
309310
Generic(String),
310311
}
311312

@@ -355,6 +356,15 @@ impl FromStr for IdlType {
355356
return Ok(IdlType::Vec(Box::new(inner_ty)));
356357
}
357358

359+
if let Some(inner) = s.strip_prefix("NonZero<") {
360+
let inner_ty = Self::from_str(
361+
inner
362+
.strip_suffix('>')
363+
.ok_or_else(|| anyhow!("Invalid NonZero"))?,
364+
)?;
365+
return Ok(IdlType::NonZero(Box::new(inner_ty)));
366+
}
367+
358368
if s.starts_with('[') {
359369
fn array_from_str(inner: &str) -> IdlType {
360370
match inner.strip_suffix(']') {
@@ -499,4 +509,12 @@ mod tests {
499509
}
500510
)
501511
}
512+
513+
#[test]
514+
fn nonzero() {
515+
assert_eq!(
516+
IdlType::from_str("NonZero<u64>").unwrap(),
517+
IdlType::NonZero(Box::new(IdlType::U64)),
518+
)
519+
}
502520
}

idl/src/convert.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ mod legacy {
244244
Array(Box<IdlType>, usize),
245245
GenericLenArray(Box<IdlType>, String),
246246
Generic(String),
247+
NonZero(Box<IdlType>),
247248
DefinedWithTypeArgs {
248249
name: String,
249250
args: Vec<IdlDefinedTypeArg>,
@@ -491,6 +492,7 @@ mod legacy {
491492
IdlType::GenericLenArray(ty, generic) => {
492493
t::IdlType::Array(ty.into(), t::IdlArrayLen::Generic(generic))
493494
}
495+
IdlType::NonZero(ty) => t::IdlType::NonZero(ty.into()),
494496
_ => serde_json::to_value(value)
495497
.and_then(serde_json::from_value)
496498
.unwrap(),

lang/attribute/program/src/declare_program/common.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub fn convert_idl_type_to_str(ty: &IdlType) -> String {
8989
.map(|generics| format!("{name}<{generics}>"))
9090
.unwrap_or(name.into()),
9191
IdlType::Generic(ty) => ty.into(),
92+
IdlType::NonZero(ty) => format!("NonZero<{}>", convert_idl_type_to_str(ty)),
9293
_ => unimplemented!("{ty:?}"),
9394
}
9495
}
@@ -309,6 +310,7 @@ fn can_derive_copy_ty(ty: &IdlType, ty_defs: &[IdlTypeDef]) -> bool {
309310
.map(|ty_def| can_derive_copy(ty_def, ty_defs))
310311
.expect("Type def must exist"),
311312
IdlType::Bytes | IdlType::String | IdlType::Vec(_) | IdlType::Generic(_) => false,
313+
IdlType::NonZero(inner) => can_derive_copy_ty(inner, ty_defs),
312314
_ => true,
313315
}
314316
}
@@ -333,6 +335,7 @@ fn can_derive_default_ty(ty: &IdlType, ty_defs: &[IdlTypeDef]) -> bool {
333335
.map(|ty_def| can_derive_default(ty_def, ty_defs))
334336
.expect("Type def must exist"),
335337
IdlType::Generic(_) => false,
338+
IdlType::NonZero(_) => false,
336339
_ => true,
337340
}
338341
}

lang/syn/src/idl/defined.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,15 @@ pub fn gen_idl_type(
416416
syn::Type::Path(path) if the_only_segment_is(path, "i128") => {
417417
Ok((quote! { #idl::IdlType::I128 }, vec![]))
418418
}
419+
syn::Type::Path(path) if the_only_segment_is(path, "NonZero") => {
420+
let segment = get_first_segment(path);
421+
let arg = get_angle_bracketed_type_args(segment)
422+
.into_iter()
423+
.next()
424+
.unwrap();
425+
let (inner, defined) = gen_idl_type(arg, generic_params)?;
426+
Ok((quote! { #idl::IdlType::NonZero(Box::new(#inner)) }, defined))
427+
}
419428
syn::Type::Path(path)
420429
if the_only_segment_is(path, "String") || the_only_segment_is(path, "str") =>
421430
{

0 commit comments

Comments
 (0)