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;
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();
value
.serialize(toml::ser::ValueSerializer::new(&mut result))

View file

@ -1,10 +1,10 @@
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")]
pub enum RoomsSortOrder {
#[default]
@ -12,18 +12,6 @@ pub enum RoomsSortOrder {
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
#[derive(Debug, Clone, Default, Deserialize, Document)]
pub struct EuphRoom {

View file

@ -1,7 +1,7 @@
use proc_macro2::TokenStream;
use quote::quote;
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};
@ -75,11 +75,7 @@ impl FieldInfo {
}
}
pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
let Data::Struct(data) = input.data else {
return Err(syn::Error::new(input.span(), "must be a struct"));
};
fn from_struct(ident: Ident, data: DataStruct) -> syn::Result<TokenStream> {
let mut fields = vec![];
for field in data.fields {
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!(
impl crate::doc::Document for #ident {
fn doc() -> crate::doc::Doc {
@ -145,3 +140,33 @@ pub fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
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"),
}
}