From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- third_party/rust/uniffi_macros/src/default.rs | 133 ++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 third_party/rust/uniffi_macros/src/default.rs (limited to 'third_party/rust/uniffi_macros/src/default.rs') diff --git a/third_party/rust/uniffi_macros/src/default.rs b/third_party/rust/uniffi_macros/src/default.rs new file mode 100644 index 0000000000..000c205845 --- /dev/null +++ b/third_party/rust/uniffi_macros/src/default.rs @@ -0,0 +1,133 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use crate::util::kw; +use proc_macro2::TokenStream; +use quote::{quote, ToTokens}; +use syn::{ + bracketed, parenthesized, + parse::{Nothing, Parse, ParseStream}, + token::{Bracket, Paren}, + Lit, +}; + +/// Default value +#[derive(Clone)] +pub enum DefaultValue { + Literal(Lit), + None(kw::None), + Some { + some: kw::Some, + paren: Paren, + inner: Box, + }, + EmptySeq(Bracket), +} + +impl ToTokens for DefaultValue { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + DefaultValue::Literal(lit) => lit.to_tokens(tokens), + DefaultValue::None(kw) => kw.to_tokens(tokens), + DefaultValue::Some { inner, .. } => tokens.extend(quote! { Some(#inner) }), + DefaultValue::EmptySeq(_) => tokens.extend(quote! { [] }), + } + } +} + +impl Parse for DefaultValue { + fn parse(input: ParseStream<'_>) -> syn::Result { + let lookahead = input.lookahead1(); + if lookahead.peek(kw::None) { + let none_kw: kw::None = input.parse()?; + Ok(Self::None(none_kw)) + } else if lookahead.peek(kw::Some) { + let some: kw::Some = input.parse()?; + let content; + let paren = parenthesized!(content in input); + Ok(Self::Some { + some, + paren, + inner: content.parse()?, + }) + } else if lookahead.peek(Bracket) { + let content; + let bracket = bracketed!(content in input); + content.parse::()?; + Ok(Self::EmptySeq(bracket)) + } else { + Ok(Self::Literal(input.parse()?)) + } + } +} + +impl DefaultValue { + fn metadata_calls(&self) -> syn::Result { + match self { + DefaultValue::Literal(Lit::Int(i)) if !i.suffix().is_empty() => Err( + syn::Error::new_spanned(i, "integer literals with suffix not supported here"), + ), + DefaultValue::Literal(Lit::Float(f)) if !f.suffix().is_empty() => Err( + syn::Error::new_spanned(f, "float literals with suffix not supported here"), + ), + + DefaultValue::Literal(Lit::Str(s)) => Ok(quote! { + .concat_value(::uniffi::metadata::codes::LIT_STR) + .concat_str(#s) + }), + DefaultValue::Literal(Lit::Int(i)) => { + let digits = i.base10_digits(); + Ok(quote! { + .concat_value(::uniffi::metadata::codes::LIT_INT) + .concat_str(#digits) + }) + } + DefaultValue::Literal(Lit::Float(f)) => { + let digits = f.base10_digits(); + Ok(quote! { + .concat_value(::uniffi::metadata::codes::LIT_FLOAT) + .concat_str(#digits) + }) + } + DefaultValue::Literal(Lit::Bool(b)) => Ok(quote! { + .concat_value(::uniffi::metadata::codes::LIT_BOOL) + .concat_bool(#b) + }), + + DefaultValue::Literal(_) => Err(syn::Error::new_spanned( + self, + "this type of literal is not currently supported as a default", + )), + + DefaultValue::EmptySeq(_) => Ok(quote! { + .concat_value(::uniffi::metadata::codes::LIT_EMPTY_SEQ) + }), + + DefaultValue::None(_) => Ok(quote! { + .concat_value(::uniffi::metadata::codes::LIT_NONE) + }), + + DefaultValue::Some { inner, .. } => { + let inner_calls = inner.metadata_calls()?; + Ok(quote! { + .concat_value(::uniffi::metadata::codes::LIT_SOME) + #inner_calls + }) + } + } + } +} + +pub fn default_value_metadata_calls(default: &Option) -> syn::Result { + Ok(match default { + Some(default) => { + let metadata_calls = default.metadata_calls()?; + quote! { + .concat_bool(true) + #metadata_calls + } + } + None => quote! { .concat_bool(false) }, + }) +} -- cgit v1.2.3