-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate code into into stand-alone repo
Adds Cargo.toml files
- Loading branch information
1 parent
d850e7b
commit c752b5f
Showing
15 changed files
with
3,183 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/target/ | ||
**/*.rs.bk | ||
*.swp |
File renamed without changes.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "argh" | ||
version = "0.1.0" | ||
authors = ["Taylor Cramer <[email protected]>", "Benjamin Brittain<[email protected]>"] | ||
edition = "2018" | ||
license = "BSD License 2.0" | ||
description = "Derive-based argument parser optimized for code size" | ||
repository = "https://github.com/google/argh" | ||
|
||
[dependencies] | ||
argh_shared = {path = "./argh_shared"} | ||
argh_derive = {path = "./argh_derive"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
# Argh | ||
**Argh is an opinionated Derive-based argument parsing optimized for code size** | ||
**Argh is an opinionated Derive-based argument parser optimized for code size** | ||
|
||
NOTE: This is not an officially supported Google product. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "argh_derive" | ||
version = "0.1.0" | ||
authors = ["Taylor Cramer <[email protected]>", "Benjamin Brittain<[email protected]>"] | ||
edition = "2018" | ||
license = "BSD License 2.0" | ||
description = "Derive-based argument parsing optimized for code size" | ||
repository = "https://github.com/google/argh" | ||
|
||
[lib] | ||
proc-macro = true | ||
|
||
[dependencies] | ||
heck = "0.3.1" | ||
proc-macro2 = "1.0" | ||
quote = "1.0" | ||
syn = "1.0" | ||
argh_shared = {path = "../argh_shared" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
// Copyright (c) 2020 Google LLC All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
use { | ||
proc_macro2::{Span, TokenStream}, | ||
quote::ToTokens, | ||
std::cell::RefCell, | ||
}; | ||
|
||
/// A type for collecting procedural macro errors. | ||
#[derive(Default)] | ||
pub struct Errors { | ||
errors: RefCell<Vec<syn::Error>>, | ||
} | ||
|
||
/// Produce functions to expect particular variants of `syn::Lit` | ||
macro_rules! expect_lit_fn { | ||
($(($fn_name:ident, $syn_type:ident, $variant:ident, $lit_name:literal),)*) => { | ||
$( | ||
pub fn $fn_name<'a>(&self, lit: &'a syn::Lit) -> Option<&'a syn::$syn_type> { | ||
if let syn::Lit::$variant(inner) = lit { | ||
Some(inner) | ||
} else { | ||
self.unexpected_lit($lit_name, lit); | ||
None | ||
} | ||
} | ||
)* | ||
} | ||
} | ||
|
||
/// Produce functions to expect particular variants of `syn::Meta` | ||
macro_rules! expect_meta_fn { | ||
($(($fn_name:ident, $syn_type:ident, $variant:ident, $meta_name:literal),)*) => { | ||
$( | ||
pub fn $fn_name<'a>(&self, meta: &'a syn::Meta) -> Option<&'a syn::$syn_type> { | ||
if let syn::Meta::$variant(inner) = meta { | ||
Some(inner) | ||
} else { | ||
self.unexpected_meta($meta_name, meta); | ||
None | ||
} | ||
} | ||
)* | ||
} | ||
} | ||
|
||
impl Errors { | ||
/// Issue an error like: | ||
/// | ||
/// Duplicate foo attribute | ||
/// First foo attribute here | ||
pub fn duplicate_attrs( | ||
&self, | ||
attr_kind: &str, | ||
first: &impl syn::spanned::Spanned, | ||
second: &impl syn::spanned::Spanned, | ||
) { | ||
self.duplicate_attrs_inner(attr_kind, first.span(), second.span()) | ||
} | ||
|
||
fn duplicate_attrs_inner(&self, attr_kind: &str, first: Span, second: Span) { | ||
self.err_span(second, &["Duplicate ", attr_kind, " attribute"].concat()); | ||
self.err_span(first, &["First ", attr_kind, " attribute here"].concat()); | ||
} | ||
|
||
/// Error on literals, expecting attribute syntax. | ||
pub fn expect_nested_meta<'a>(&self, nm: &'a syn::NestedMeta) -> Option<&'a syn::Meta> { | ||
match nm { | ||
syn::NestedMeta::Lit(l) => { | ||
self.err(l, "Unexpected literal"); | ||
None | ||
} | ||
syn::NestedMeta::Meta(m) => Some(m), | ||
} | ||
} | ||
|
||
/// Error on attribute syntax, expecting literals | ||
pub fn expect_nested_lit<'a>(&self, nm: &'a syn::NestedMeta) -> Option<&'a syn::Lit> { | ||
match nm { | ||
syn::NestedMeta::Meta(m) => { | ||
self.err(m, "Expected literal"); | ||
None | ||
} | ||
syn::NestedMeta::Lit(l) => Some(l), | ||
} | ||
} | ||
|
||
expect_lit_fn![ | ||
(expect_lit_str, LitStr, Str, "string"), | ||
(expect_lit_char, LitChar, Char, "character"), | ||
(expect_lit_int, LitInt, Int, "integer"), | ||
]; | ||
|
||
expect_meta_fn![ | ||
(expect_meta_word, Path, Path, "path"), | ||
(expect_meta_list, MetaList, List, "list"), | ||
(expect_meta_name_value, MetaNameValue, NameValue, "name-value pair"), | ||
]; | ||
|
||
fn unexpected_lit(&self, expected: &str, found: &syn::Lit) { | ||
fn lit_kind(lit: &syn::Lit) -> &'static str { | ||
use syn::Lit::{Bool, Byte, ByteStr, Char, Float, Int, Str, Verbatim}; | ||
match lit { | ||
Str(_) => "string", | ||
ByteStr(_) => "bytestring", | ||
Byte(_) => "byte", | ||
Char(_) => "character", | ||
Int(_) => "integer", | ||
Float(_) => "float", | ||
Bool(_) => "boolean", | ||
Verbatim(_) => "unknown (possibly extra-large integer)", | ||
} | ||
} | ||
|
||
self.err( | ||
found, | ||
&["Expected ", expected, " literal, found ", lit_kind(found), " literal"].concat(), | ||
) | ||
} | ||
|
||
fn unexpected_meta(&self, expected: &str, found: &syn::Meta) { | ||
fn meta_kind(meta: &syn::Meta) -> &'static str { | ||
use syn::Meta::{List, NameValue, Path}; | ||
match meta { | ||
Path(_) => "path", | ||
List(_) => "list", | ||
NameValue(_) => "name-value pair", | ||
} | ||
} | ||
|
||
self.err( | ||
found, | ||
&["Expected ", expected, " attribute, found ", meta_kind(found), " attribute"].concat(), | ||
) | ||
} | ||
|
||
/// Issue an error relating to a particular `Spanned` structure. | ||
pub fn err(&self, spanned: &impl syn::spanned::Spanned, msg: &str) { | ||
self.err_span(spanned.span(), msg); | ||
} | ||
|
||
/// Issue an error relating to a particular `Span`. | ||
pub fn err_span(&self, span: Span, msg: &str) { | ||
self.push(syn::Error::new(span, msg)); | ||
} | ||
|
||
/// Push a `syn::Error` onto the list of errors to issue. | ||
pub fn push(&self, err: syn::Error) { | ||
self.errors.borrow_mut().push(err); | ||
} | ||
} | ||
|
||
impl ToTokens for Errors { | ||
/// Convert the errors into tokens that, when emit, will cause | ||
/// the user of the macro to receive compiler errors. | ||
fn to_tokens(&self, tokens: &mut TokenStream) { | ||
tokens.extend(self.errors.borrow().iter().map(|e| e.to_compile_error())); | ||
} | ||
} |
Oops, something went wrong.