Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for enums #33

Merged
merged 4 commits into from
Jul 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions core/src/ast/enums.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use serde::{Deserialize, Serialize};

use super::utils::get_doc_lines;
use super::Method;

/// A fieldless enum declaration in an FFI module.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Enum {
pub name: String,
pub doc_lines: String,
/// A list of variants of the enum. (name, discriminant, doc_lines)
pub variants: Vec<(String, isize, String)>,
pub methods: Vec<Method>,
}

impl From<&syn::ItemEnum> for Enum {
/// Extract an [`Enum`] metadata value from an AST node.
fn from(strct: &syn::ItemEnum) -> Enum {
let mut last_discriminant = -1;
Enum {
name: strct.ident.to_string(),
doc_lines: get_doc_lines(&strct.attrs),
variants: strct
.variants
.iter()
.map(|v| {
let new_discriminant = v
.discriminant
.as_ref()
.map(|d| {
if let syn::Expr::Lit(syn::ExprLit {
attrs: _,
lit: syn::Lit::Int(lit_int),
}) = &d.1
{
lit_int.base10_parse::<isize>().unwrap()
} else {
panic!("Expected a discriminant to be a constant integer");
}
})
.unwrap_or_else(|| last_discriminant + 1);

last_discriminant = new_discriminant;

(
v.ident.to_string(),
new_discriminant,
get_doc_lines(&v.attrs),
)
})
.collect(),
methods: vec![],
}
}
}

#[cfg(test)]
mod tests {
use insta::{self, Settings};

use quote::quote;
use syn;

use super::Enum;

#[test]
fn simple_enum() {
let mut settings = Settings::new();
settings.set_sort_maps(true);

settings.bind(|| {
insta::assert_yaml_snapshot!(Enum::from(
&syn::parse2(quote! {
/// Some docs.
enum MyLocalEnum {
Abc,
/// Some more docs.
Def
}
})
.unwrap()
));
});
}
}
3 changes: 3 additions & 0 deletions core/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ pub use modules::{File, Module};
mod structs;
pub use structs::{OpaqueStruct, Struct};

mod enums;
pub use enums::Enum;

mod types;
pub use types::{CustomType, ModSymbol, PrimitiveType, TypeName};

Expand Down
13 changes: 12 additions & 1 deletion core/src/ast/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::collections::HashMap;
use quote::ToTokens;
use syn::{ImplItem, Item, ItemMod, UseTree};

use super::{CustomType, Method, ModSymbol, OpaqueStruct, Path, Struct, TypeName};
use super::{CustomType, Enum, Method, ModSymbol, OpaqueStruct, Path, Struct, TypeName};

#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct Module {
Expand Down Expand Up @@ -99,6 +99,14 @@ impl Module {
}
}
}

Item::Enum(enm) => {
if analyze_types {
custom_types_by_name
.insert(enm.ident.to_string(), CustomType::Enum(Enum::from(enm)));
}
}

Item::Impl(ipl) => {
if analyze_types {
assert!(ipl.trait_.is_none());
Expand Down Expand Up @@ -126,6 +134,9 @@ impl Module {
CustomType::Opaque(strct) => {
strct.methods.append(&mut new_methods);
}
CustomType::Enum(enm) => {
enm.methods.append(&mut new_methods);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
source: core/src/ast/enums.rs
expression: "Enum::from(&syn::parse2(quote! {\n /// Some docs.\n enum MyLocalEnum\n {\n Abc, /// Some more docs.\n Def\n }\n }).unwrap())"

---
name: MyLocalEnum
doc_lines: Some docs.
variants:
- - Abc
- 0
- ""
- - Def
- 1
- Some more docs.
methods: []

9 changes: 7 additions & 2 deletions core/src/ast/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ use lazy_static::lazy_static;
use std::collections::HashMap;
use std::iter::FromIterator;

use super::{Method, OpaqueStruct, Path, Struct};
use super::{Enum, Method, OpaqueStruct, Path, Struct};

/// A type declared inside a Diplomat-annotated module.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub enum CustomType {
/// A non-opaque struct whose fields will be visible across the FFI boundary.
Struct(Struct),
// TODO(shadaj): Enum
/// A struct annotated with [`diplomat::opaque`] whose fields are not visible.
Opaque(OpaqueStruct),
/// A fieldless enum.
Enum(Enum),
}

impl CustomType {
Expand All @@ -25,6 +26,7 @@ impl CustomType {
match self {
CustomType::Struct(strct) => &strct.name,
CustomType::Opaque(strct) => &strct.name,
CustomType::Enum(enm) => &enm.name,
}
}

Expand All @@ -33,6 +35,7 @@ impl CustomType {
match self {
CustomType::Struct(strct) => &strct.methods,
CustomType::Opaque(strct) => &strct.methods,
CustomType::Enum(enm) => &enm.methods,
}
}

Expand All @@ -41,6 +44,7 @@ impl CustomType {
match self {
CustomType::Struct(strct) => &strct.doc_lines,
CustomType::Opaque(strct) => &strct.doc_lines,
CustomType::Enum(enm) => &enm.doc_lines,
}
}

Expand All @@ -61,6 +65,7 @@ impl CustomType {
}
}
CustomType::Opaque(_) => {}
CustomType::Enum(_) => {}
}

for method in self.methods().iter() {
Expand Down
21 changes: 19 additions & 2 deletions example/c/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,26 @@ typedef struct ICU4XFixedDecimal ICU4XFixedDecimal;

typedef struct ICU4XFixedDecimalFormat ICU4XFixedDecimalFormat;

enum ICU4XFixedDecimalGroupingStrategy {
ICU4XFixedDecimalGroupingStrategy_Auto = 0,
ICU4XFixedDecimalGroupingStrategy_Never = 1,
ICU4XFixedDecimalGroupingStrategy_Always = 2,
ICU4XFixedDecimalGroupingStrategy_Min2 = 3,
};

enum ICU4XFixedDecimalSignDisplay {
ICU4XFixedDecimalSignDisplay_Auto = 0,
ICU4XFixedDecimalSignDisplay_Never = 1,
ICU4XFixedDecimalSignDisplay_Always = 2,
ICU4XFixedDecimalSignDisplay_ExceptZero = 3,
ICU4XFixedDecimalSignDisplay_Negative = 4,
};

typedef struct ICU4XLocale ICU4XLocale;

typedef struct ICU4XFixedDecimalFormatOptions {
uint8_t grouping_strategy;
uint8_t sign_display;
ssize_t grouping_strategy;
ssize_t sign_display;
} ICU4XFixedDecimalFormatOptions;

typedef struct ICU4XFixedDecimalFormatResult {
Expand Down Expand Up @@ -45,6 +60,8 @@ void ICU4XFixedDecimalFormat_destroy(ICU4XFixedDecimalFormat* self);
ICU4XFixedDecimalFormatOptions ICU4XFixedDecimalFormatOptions_default();
void ICU4XFixedDecimalFormatOptions_destroy(ICU4XFixedDecimalFormatOptions* self);
void ICU4XFixedDecimalFormatResult_destroy(ICU4XFixedDecimalFormatResult* self);
void ICU4XFixedDecimalGroupingStrategy_destroy(ssize_t* self);
void ICU4XFixedDecimalSignDisplay_destroy(ssize_t* self);

ICU4XLocale* ICU4XLocale_new(const char* name_data, size_t name_len);
void ICU4XLocale_destroy(ICU4XLocale* self);
Expand Down
21 changes: 19 additions & 2 deletions example/cpp/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,26 @@ typedef struct ICU4XFixedDecimal ICU4XFixedDecimal;

typedef struct ICU4XFixedDecimalFormat ICU4XFixedDecimalFormat;

enum ICU4XFixedDecimalGroupingStrategy {
ICU4XFixedDecimalGroupingStrategy_Auto = 0,
ICU4XFixedDecimalGroupingStrategy_Never = 1,
ICU4XFixedDecimalGroupingStrategy_Always = 2,
ICU4XFixedDecimalGroupingStrategy_Min2 = 3,
};

enum ICU4XFixedDecimalSignDisplay {
ICU4XFixedDecimalSignDisplay_Auto = 0,
ICU4XFixedDecimalSignDisplay_Never = 1,
ICU4XFixedDecimalSignDisplay_Always = 2,
ICU4XFixedDecimalSignDisplay_ExceptZero = 3,
ICU4XFixedDecimalSignDisplay_Negative = 4,
};

typedef struct ICU4XLocale ICU4XLocale;

typedef struct ICU4XFixedDecimalFormatOptions {
uint8_t grouping_strategy;
uint8_t sign_display;
ssize_t grouping_strategy;
ssize_t sign_display;
} ICU4XFixedDecimalFormatOptions;

typedef struct ICU4XFixedDecimalFormatResult {
Expand Down Expand Up @@ -45,6 +60,8 @@ void ICU4XFixedDecimalFormat_destroy(ICU4XFixedDecimalFormat* self);
ICU4XFixedDecimalFormatOptions ICU4XFixedDecimalFormatOptions_default();
void ICU4XFixedDecimalFormatOptions_destroy(ICU4XFixedDecimalFormatOptions* self);
void ICU4XFixedDecimalFormatResult_destroy(ICU4XFixedDecimalFormatResult* self);
void ICU4XFixedDecimalGroupingStrategy_destroy(ssize_t* self);
void ICU4XFixedDecimalSignDisplay_destroy(ssize_t* self);

ICU4XLocale* ICU4XLocale_new(const char* name_data, size_t name_len);
void ICU4XLocale_destroy(ICU4XLocale* self);
Expand Down
25 changes: 21 additions & 4 deletions example/cpp/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ struct ICU4XFixedDecimalFormatOptions;

struct ICU4XFixedDecimalFormatResult;

enum struct ICU4XFixedDecimalGroupingStrategy : ssize_t {
Auto = 0,
Never = 1,
Always = 2,
Min2 = 3,
};

enum struct ICU4XFixedDecimalSignDisplay : ssize_t {
Auto = 0,
Never = 1,
Always = 2,
ExceptZero = 3,
Negative = 4,
};

class ICU4XLocale;

struct ICU4XDataProviderDeleter {
Expand Down Expand Up @@ -86,8 +101,8 @@ struct ICU4XFixedDecimalFormatOptionsDeleter {
};
struct ICU4XFixedDecimalFormatOptions {
public:
uint8_t grouping_strategy;
uint8_t sign_display;
ICU4XFixedDecimalGroupingStrategy grouping_strategy;
ICU4XFixedDecimalSignDisplay sign_display;
static ICU4XFixedDecimalFormatOptions default_();
};

Expand Down Expand Up @@ -124,7 +139,7 @@ std::string ICU4XFixedDecimal::to_string() {

ICU4XFixedDecimalFormatResult ICU4XFixedDecimalFormat::try_new(const ICU4XLocale& locale, const ICU4XDataProvider& provider, ICU4XFixedDecimalFormatOptions options) {
ICU4XFixedDecimalFormatOptions diplomat_wrapped_struct_options = options;
capi::ICU4XFixedDecimalFormatResult diplomat_raw_struct_out_value = capi::ICU4XFixedDecimalFormat_try_new(locale.AsFFI(), provider.AsFFI(), capi::ICU4XFixedDecimalFormatOptions{ .grouping_strategy = diplomat_wrapped_struct_options.grouping_strategy, .sign_display = diplomat_wrapped_struct_options.sign_display });
capi::ICU4XFixedDecimalFormatResult diplomat_raw_struct_out_value = capi::ICU4XFixedDecimalFormat_try_new(locale.AsFFI(), provider.AsFFI(), capi::ICU4XFixedDecimalFormatOptions{ .grouping_strategy = static_cast<ssize_t>(diplomat_wrapped_struct_options.grouping_strategy), .sign_display = static_cast<ssize_t>(diplomat_wrapped_struct_options.sign_display) });
auto diplomat_optional_raw_out_value_fdf = diplomat_raw_struct_out_value.fdf;
std::optional<ICU4XFixedDecimalFormat> diplomat_optional_out_value_fdf;
if (diplomat_optional_raw_out_value_fdf != nullptr) {
Expand All @@ -143,10 +158,12 @@ std::string ICU4XFixedDecimalFormat::format_write(const ICU4XFixedDecimal& value

ICU4XFixedDecimalFormatOptions ICU4XFixedDecimalFormatOptions::default_() {
capi::ICU4XFixedDecimalFormatOptions diplomat_raw_struct_out_value = capi::ICU4XFixedDecimalFormatOptions_default();
return ICU4XFixedDecimalFormatOptions{ .grouping_strategy = std::move(diplomat_raw_struct_out_value.grouping_strategy), .sign_display = std::move(diplomat_raw_struct_out_value.sign_display) };
return ICU4XFixedDecimalFormatOptions{ .grouping_strategy = std::move(ICU4XFixedDecimalGroupingStrategy{ diplomat_raw_struct_out_value.grouping_strategy }), .sign_display = std::move(ICU4XFixedDecimalSignDisplay{ diplomat_raw_struct_out_value.sign_display }) };
}




ICU4XLocale ICU4XLocale::new_(const std::string name) {
return ICU4XLocale(capi::ICU4XLocale_new(name.data(), name.length()));
}
Loading