Derive Document for simple enums

This commit is contained in:
Joscha 2023-04-27 20:34:46 +02:00
parent 458025b8bf
commit 6f85995379
3 changed files with 36 additions and 23 deletions

View file

@ -7,7 +7,7 @@ use cove_input::KeyBinding;
pub use cove_macro::Document; pub use cove_macro::Document;
use serde::Serialize; use serde::Serialize;
pub(crate) fn toml_value_as_markdown<T: Serialize>(value: &T) -> String { pub fn toml_value_as_markdown<T: Serialize>(value: &T) -> String {
let mut result = String::new(); let mut result = String::new();
value value
.serialize(toml::ser::ValueSerializer::new(&mut result)) .serialize(toml::ser::ValueSerializer::new(&mut result))

View file

@ -1,10 +1,10 @@
use std::collections::HashMap; use std::collections::HashMap;
use serde::Deserialize; use serde::{Deserialize, Serialize};
use crate::doc::{Doc, Document}; use crate::doc::Document;
#[derive(Debug, Clone, Copy, Default, Deserialize)] #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, Document)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum RoomsSortOrder { pub enum RoomsSortOrder {
#[default] #[default]
@ -12,18 +12,6 @@ pub enum RoomsSortOrder {
Importance, Importance,
} }
impl Document for RoomsSortOrder {
fn doc() -> Doc {
let mut doc = String::doc();
doc.value_info.values = Some(vec![
// TODO Generate by serializing
"`alphabet`".to_string(),
"`importance`".to_string(),
]);
doc
}
}
// TODO Mark favourite rooms via printable ascii characters // TODO Mark favourite rooms via printable ascii characters
#[derive(Debug, Clone, Default, Deserialize, Document)] #[derive(Debug, Clone, Default, Deserialize, Document)]
pub struct EuphRoom { pub struct EuphRoom {

View file

@ -1,7 +1,7 @@
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::quote;
use syn::spanned::Spanned; use syn::spanned::Spanned;
use syn::{Data, DeriveInput, ExprPath, Field, LitStr, Type}; use syn::{Data, DataEnum, DataStruct, DeriveInput, ExprPath, Field, Ident, LitStr, Type};
use crate::util::{self, docstring}; use crate::util::{self, docstring};
@ -75,11 +75,7 @@ impl FieldInfo {
} }
} }
pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> { fn from_struct(ident: Ident, data: DataStruct) -> syn::Result<TokenStream> {
let Data::Struct(data) = input.data else {
return Err(syn::Error::new(input.span(), "must be a struct"));
};
let mut fields = vec![]; let mut fields = vec![];
for field in data.fields { for field in data.fields {
let Some(ident) = field.ident.as_ref() else { let Some(ident) = field.ident.as_ref() else {
@ -129,7 +125,6 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
}); });
} }
let ident = input.ident;
let tokens = quote!( let tokens = quote!(
impl crate::doc::Document for #ident { impl crate::doc::Document for #ident {
fn doc() -> crate::doc::Doc { fn doc() -> crate::doc::Doc {
@ -145,3 +140,33 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
Ok(tokens) Ok(tokens)
} }
fn from_enum(ident: Ident, data: DataEnum) -> syn::Result<TokenStream> {
let mut values = vec![];
for variant in data.variants {
let ident = variant.ident;
values.push(quote! {
crate::doc::toml_value_as_markdown(&Self::#ident)
});
}
let tokens = quote!(
impl crate::doc::Document for #ident {
fn doc() -> crate::doc::Doc {
let mut doc = <String as crate::doc::Document>::doc();
doc.value_info.values = Some(vec![ #( #values ),* ]);
doc
}
}
);
Ok(tokens)
}
pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
match input.data {
Data::Struct(data) => from_struct(input.ident, data),
Data::Enum(data) => from_enum(input.ident, data),
Data::Union(_) => util::bail(input.span(), "must be an enum or a struct"),
}
}