rustyline-derive-0.10.0/.cargo_vcs_info.json0000644000000001560000000000100144260ustar { "git": { "sha1": "64e1082750a991b9fe18383a954f5eab0a29e039" }, "path_in_vcs": "rustyline-derive" }rustyline-derive-0.10.0/Cargo.toml0000644000000023570000000000100124310ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "rustyline-derive" version = "0.10.0" authors = ["gwenn"] description = "Rustyline macros implementation of #[derive(Completer, Helper, Hinter, Highlighter)]" keywords = ["readline"] categories = ["command-line-interface"] license = "MIT" repository = "https://github.com/kkawakam/rustyline" resolver = "2" [lib] proc-macro = true [dependencies.proc-macro2] version = "1.0" default-features = false [dependencies.quote] version = "1.0" default-features = false [dependencies.syn] version = "2.0" features = [ "derive", "parsing", "printing", "proc-macro", ] default-features = false [badges.appveyor] repository = "kkawakam/rustyline" [badges.maintenance] status = "actively-developed" [badges.travis-ci] repository = "kkawakam/rustyline" rustyline-derive-0.10.0/Cargo.toml.orig000064400000000000000000000014041046102023000161020ustar 00000000000000[package] name = "rustyline-derive" version = "0.10.0" authors = ["gwenn"] edition = "2018" description = "Rustyline macros implementation of #[derive(Completer, Helper, Hinter, Highlighter)]" repository = "https://github.com/kkawakam/rustyline" #readme = "README.md" keywords = ["readline"] license = "MIT" categories = ["command-line-interface"] [badges] travis-ci = { repository = "kkawakam/rustyline" } appveyor = { repository = "kkawakam/rustyline" } maintenance = { status = "actively-developed" } [lib] proc-macro = true [dependencies] syn = { version = "2.0", default-features = false, features = ["derive", "parsing", "printing", "proc-macro"] } quote = { version = "1.0", default-features = false } proc-macro2 = { version = "1.0", default-features = false } rustyline-derive-0.10.0/src/lib.rs000064400000000000000000000202721046102023000151220ustar 00000000000000use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::{parse_macro_input, Data, DeriveInput, Field, Index, Path}; fn get_field_by_attr<'a>(data: &'a Data, ident: &str) -> Option<(usize, &'a Field)> { if let Data::Struct(struct_data) = &data { let mut fields = struct_data.fields.iter().enumerate().filter(|(_, field)| { field.attrs.iter().any(|attr| { attr.path().is_ident("rustyline") && attr .parse_args::() .map_or(false, |arg| arg.is_ident(ident)) }) }); let field = fields.next(); if fields.next().is_some() { panic!("Only one {:} field is allowed.", ident); } field } else { None } } fn field_name_or_index_token(index: usize, field: &Field) -> TokenStream2 { if let Some(ident) = field.ident.as_ref() { quote!(#ident) } else { let index = Index::from(index); quote!(#index) } } #[proc_macro_derive(Completer, attributes(rustyline))] pub fn completer_macro_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; let generics = input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let expanded = if let Some((index, field)) = get_field_by_attr(&input.data, "Completer") { let field_name_or_index = field_name_or_index_token(index, field); let field_type = &field.ty; quote! { #[automatically_derived] impl #impl_generics ::rustyline::completion::Completer for #name #ty_generics #where_clause { type Candidate = <#field_type as ::rustyline::completion::Completer>::Candidate; fn complete( &self, line: &str, pos: usize, ctx: &::rustyline::Context<'_>, ) -> ::rustyline::Result<(usize, ::std::vec::Vec)> { ::rustyline::completion::Completer::complete(&self.#field_name_or_index, line, pos, ctx) } fn update(&self, line: &mut ::rustyline::line_buffer::LineBuffer, start: usize, elected: &str, cl: &mut ::rustyline::Changeset) { ::rustyline::completion::Completer::update(&self.#field_name_or_index, line, start, elected, cl) } } } } else { quote! { #[automatically_derived] impl #impl_generics ::rustyline::completion::Completer for #name #ty_generics #where_clause { type Candidate = ::std::string::String; } } }; TokenStream::from(expanded) } #[proc_macro_derive(Helper)] pub fn helper_macro_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; let generics = input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let expanded = quote! { #[automatically_derived] impl #impl_generics ::rustyline::Helper for #name #ty_generics #where_clause { } }; TokenStream::from(expanded) } #[proc_macro_derive(Highlighter, attributes(rustyline))] pub fn highlighter_macro_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; let generics = input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let expanded = if let Some((index, field)) = get_field_by_attr(&input.data, "Highlighter") { let field_name_or_index = field_name_or_index_token(index, field); quote! { #[automatically_derived] impl #impl_generics ::rustyline::highlight::Highlighter for #name #ty_generics #where_clause { fn highlight<'l>(&self, line: &'l str, pos: usize) -> ::std::borrow::Cow<'l, str> { ::rustyline::highlight::Highlighter::highlight(&self.#field_name_or_index, line, pos) } fn highlight_prompt<'b, 's: 'b, 'p: 'b>( &'s self, prompt: &'p str, default: bool, ) -> ::std::borrow::Cow<'b, str> { ::rustyline::highlight::Highlighter::highlight_prompt(&self.#field_name_or_index, prompt, default) } fn highlight_hint<'h>(&self, hint: &'h str) -> ::std::borrow::Cow<'h, str> { ::rustyline::highlight::Highlighter::highlight_hint(&self.#field_name_or_index, hint) } fn highlight_candidate<'c>( &self, candidate: &'c str, completion: ::rustyline::config::CompletionType, ) -> ::std::borrow::Cow<'c, str> { ::rustyline::highlight::Highlighter::highlight_candidate(&self.#field_name_or_index, candidate, completion) } fn highlight_char(&self, line: &str, pos: usize, forced: bool) -> bool { ::rustyline::highlight::Highlighter::highlight_char(&self.#field_name_or_index, line, pos, forced) } } } } else { quote! { #[automatically_derived] impl #impl_generics ::rustyline::highlight::Highlighter for #name #ty_generics #where_clause { } } }; TokenStream::from(expanded) } #[proc_macro_derive(Hinter, attributes(rustyline))] pub fn hinter_macro_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; let generics = input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let expanded = if let Some((index, field)) = get_field_by_attr(&input.data, "Hinter") { let field_name_or_index = field_name_or_index_token(index, field); let field_type = &field.ty; quote! { #[automatically_derived] impl #impl_generics ::rustyline::hint::Hinter for #name #ty_generics #where_clause { type Hint = <#field_type as ::rustyline::hint::Hinter>::Hint; fn hint(&self, line: &str, pos: usize, ctx: &::rustyline::Context<'_>) -> ::std::option::Option { ::rustyline::hint::Hinter::hint(&self.#field_name_or_index, line, pos, ctx) } } } } else { quote! { #[automatically_derived] impl #impl_generics ::rustyline::hint::Hinter for #name #ty_generics #where_clause { type Hint = ::std::string::String; } } }; TokenStream::from(expanded) } #[proc_macro_derive(Validator, attributes(rustyline))] pub fn validator_macro_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; let generics = input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let expanded = if let Some((index, field)) = get_field_by_attr(&input.data, "Validator") { let field_name_or_index = field_name_or_index_token(index, field); quote! { #[automatically_derived] impl #impl_generics ::rustyline::validate::Validator for #name #ty_generics #where_clause { fn validate( &self, ctx: &mut ::rustyline::validate::ValidationContext, ) -> ::rustyline::Result<::rustyline::validate::ValidationResult> { ::rustyline::validate::Validator::validate(&self.#field_name_or_index, ctx) } fn validate_while_typing(&self) -> bool { ::rustyline::validate::Validator::validate_while_typing(&self.#field_name_or_index) } } } } else { quote! { #[automatically_derived] impl #impl_generics ::rustyline::validate::Validator for #name #ty_generics #where_clause { } } }; TokenStream::from(expanded) }