Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/string_enum/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/string_enum/.cargo-checksum.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"files":{"Cargo.toml":"8c271c099b27139d97365c056a01ecb1c6cde97fea3df60acc4fda68f667d1e8","src/lib.rs":"03d1549b5d1c6ab1821fbb58a010fc2cf9a611e20598534a9cbf8cc09cb1d00d","tests/simple.rs":"d8d95d1bc5435a3b0e181306dc1b9ca94ecf362ad145e710aa9352352e04f67d"},"package":"8fa4d4f81d7c05b9161f8de839975d3326328b8ba2831164b465524cc2f55252"}
|
||||
49
third-party/vendor/string_enum/Cargo.toml
vendored
Normal file
49
third-party/vendor/string_enum/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# 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 = "2021"
|
||||
name = "string_enum"
|
||||
version = "0.4.1"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
description = "String based enum."
|
||||
documentation = "https://rustdoc.swc.rs/string_enum/"
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
resolver = "1"
|
||||
|
||||
[lib]
|
||||
bench = false
|
||||
proc-macro = true
|
||||
|
||||
[dependencies.pmutil]
|
||||
version = "0.6.1"
|
||||
|
||||
[dependencies.proc-macro2]
|
||||
version = "1"
|
||||
|
||||
[dependencies.quote]
|
||||
version = "1"
|
||||
|
||||
[dependencies.swc_macros_common]
|
||||
version = "0.3.8"
|
||||
|
||||
[dependencies.syn]
|
||||
version = "2"
|
||||
features = [
|
||||
"full",
|
||||
"parsing",
|
||||
"printing",
|
||||
"extra-traits",
|
||||
]
|
||||
|
||||
[dev-dependencies.serde]
|
||||
version = "1"
|
||||
413
third-party/vendor/string_enum/src/lib.rs
vendored
Normal file
413
third-party/vendor/string_enum/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
#![recursion_limit = "1024"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use pmutil::{smart_quote, Quote};
|
||||
use quote::quote_spanned;
|
||||
use swc_macros_common::prelude::*;
|
||||
use syn::{self, parse::Parse, *};
|
||||
|
||||
/// Creates `.as_str()` and then implements `Debug` and `Display` using it.
|
||||
///
|
||||
///# Input
|
||||
/// Enum with \`str_value\`-style **doc** comment for each variant.
|
||||
///
|
||||
/// e.g.
|
||||
///
|
||||
///```no_run
|
||||
/// pub enum BinOp {
|
||||
/// /// `+`
|
||||
/// Add,
|
||||
/// /// `-`
|
||||
/// Minus,
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Currently, \`str_value\` must be live in it's own line.
|
||||
///
|
||||
///# Output
|
||||
///
|
||||
/// - `pub fn as_str(&self) -> &'static str`
|
||||
/// - `impl serde::Serialize` with `cfg(feature = "serde")`
|
||||
/// - `impl serde::Deserialize` with `cfg(feature = "serde")`
|
||||
/// - `impl FromStr`
|
||||
/// - `impl Debug`
|
||||
/// - `impl Display`
|
||||
///
|
||||
///# Example
|
||||
///
|
||||
///
|
||||
///```
|
||||
/// #[macro_use]
|
||||
/// extern crate string_enum;
|
||||
/// extern crate serde;
|
||||
///
|
||||
/// #[derive(StringEnum)]
|
||||
/// pub enum Tokens {
|
||||
/// /// `a`
|
||||
/// A,
|
||||
/// /// `bar`
|
||||
/// B,
|
||||
/// }
|
||||
/// # fn main() {
|
||||
///
|
||||
/// assert_eq!(Tokens::A.as_str(), "a");
|
||||
/// assert_eq!(Tokens::B.as_str(), "bar");
|
||||
///
|
||||
/// assert_eq!(Tokens::A.to_string(), "a");
|
||||
/// assert_eq!(format!("{:?}", Tokens::A), format!("{:?}", "a"));
|
||||
///
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
///
|
||||
/// All formatting flags are handled correctly.
|
||||
#[proc_macro_derive(StringEnum, attributes(string_enum))]
|
||||
pub fn derive_string_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = syn::parse::<syn::DeriveInput>(input)
|
||||
.map(From::from)
|
||||
.expect("failed to parse derive input");
|
||||
let mut tts = TokenStream::new();
|
||||
|
||||
make_as_str(&input).to_tokens(&mut tts);
|
||||
make_from_str(&input).to_tokens(&mut tts);
|
||||
|
||||
make_serialize(&input).to_tokens(&mut tts);
|
||||
make_deserialize(&input).to_tokens(&mut tts);
|
||||
|
||||
derive_fmt(&input, quote_spanned!(Span::call_site() => std::fmt::Debug)).to_tokens(&mut tts);
|
||||
derive_fmt(
|
||||
&input,
|
||||
quote_spanned!(Span::call_site() => std::fmt::Display),
|
||||
)
|
||||
.to_tokens(&mut tts);
|
||||
|
||||
print("derive(StringEnum)", tts)
|
||||
}
|
||||
|
||||
fn derive_fmt(i: &DeriveInput, trait_path: TokenStream) -> ItemImpl {
|
||||
Quote::new(def_site::<Span>())
|
||||
.quote_with(smart_quote!(
|
||||
Vars {
|
||||
Trait: trait_path,
|
||||
Type: &i.ident,
|
||||
as_str: make_as_str_ident(),
|
||||
},
|
||||
{
|
||||
impl Trait for Type {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let s = self.as_str();
|
||||
Trait::fmt(s, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
.parse::<ItemImpl>()
|
||||
.with_generics(i.generics.clone())
|
||||
}
|
||||
|
||||
fn get_str_value(attrs: &[Attribute]) -> String {
|
||||
// TODO: Accept multiline string
|
||||
let docs: Vec<_> = attrs.iter().filter_map(doc_str).collect();
|
||||
for raw_line in docs {
|
||||
let line = raw_line.trim();
|
||||
if line.starts_with('`') && line.ends_with('`') {
|
||||
let mut s: String = line.split_at(1).1.into();
|
||||
let new_len = s.len() - 1;
|
||||
s.truncate(new_len);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
panic!("StringEnum: Cannot determine string value of this variant")
|
||||
}
|
||||
|
||||
fn make_from_str(i: &DeriveInput) -> ItemImpl {
|
||||
let arms = Binder::new_from(i)
|
||||
.variants()
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
// Qualified path of variant.
|
||||
let qual_name = v.qual_path();
|
||||
|
||||
let str_value = get_str_value(v.attrs());
|
||||
|
||||
let mut pat: Pat = Pat::Lit(ExprLit {
|
||||
attrs: Default::default(),
|
||||
lit: Lit::Str(LitStr::new(&str_value, Span::call_site())),
|
||||
});
|
||||
|
||||
// Handle `string_enum(alias("foo"))`
|
||||
for attr in v
|
||||
.attrs()
|
||||
.iter()
|
||||
.filter(|attr| is_attr_name(attr, "string_enum"))
|
||||
{
|
||||
if let Meta::List(meta) = &attr.meta {
|
||||
let mut cases = Punctuated::default();
|
||||
|
||||
cases.push(pat);
|
||||
|
||||
for item in parse2::<FieldAttr>(meta.tokens.clone())
|
||||
.expect("failed to parse `#[string_enum]`")
|
||||
.aliases
|
||||
{
|
||||
cases.push(Pat::Lit(PatLit {
|
||||
attrs: Default::default(),
|
||||
lit: Lit::Str(item.alias),
|
||||
}));
|
||||
}
|
||||
|
||||
pat = Pat::Or(PatOr {
|
||||
attrs: Default::default(),
|
||||
leading_vert: None,
|
||||
cases,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
panic!("Unsupported meta: {:#?}", attr.meta);
|
||||
}
|
||||
|
||||
let body = match *v.data() {
|
||||
Fields::Unit => Box::new(
|
||||
Quote::new(def_site::<Span>())
|
||||
.quote_with(smart_quote!(Vars { qual_name }, { return Ok(qual_name) }))
|
||||
.parse(),
|
||||
),
|
||||
_ => unreachable!("StringEnum requires all variants not to have fields"),
|
||||
};
|
||||
|
||||
Arm {
|
||||
body,
|
||||
attrs: v
|
||||
.attrs()
|
||||
.iter()
|
||||
.filter(|attr| is_attr_name(attr, "cfg"))
|
||||
.cloned()
|
||||
.collect(),
|
||||
pat,
|
||||
guard: None,
|
||||
fat_arrow_token: def_site(),
|
||||
comma: Some(def_site()),
|
||||
}
|
||||
})
|
||||
.chain(::std::iter::once({
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(Vars{}, {
|
||||
_ => Err(())
|
||||
}))
|
||||
.parse()
|
||||
}))
|
||||
.collect();
|
||||
|
||||
let body = Expr::Match(ExprMatch {
|
||||
attrs: Default::default(),
|
||||
match_token: def_site(),
|
||||
brace_token: def_site(),
|
||||
expr: Box::new(
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(Vars {}, { s }))
|
||||
.parse(),
|
||||
),
|
||||
arms,
|
||||
});
|
||||
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(
|
||||
Vars {
|
||||
Type: &i.ident,
|
||||
body,
|
||||
},
|
||||
{
|
||||
impl ::std::str::FromStr for Type {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, ()> {
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
.parse::<ItemImpl>()
|
||||
.with_generics(i.generics.clone())
|
||||
}
|
||||
|
||||
fn make_as_str(i: &DeriveInput) -> ItemImpl {
|
||||
let arms = Binder::new_from(i)
|
||||
.variants()
|
||||
.into_iter()
|
||||
.map(|v| {
|
||||
// Qualified path of variant.
|
||||
let qual_name = v.qual_path();
|
||||
|
||||
let str_value = get_str_value(v.attrs());
|
||||
|
||||
let body = Box::new(
|
||||
Quote::new(def_site::<Span>())
|
||||
.quote_with(smart_quote!(Vars { str_value }, { return str_value }))
|
||||
.parse(),
|
||||
);
|
||||
|
||||
let pat = match *v.data() {
|
||||
Fields::Unit => Box::new(Pat::Path(PatPath {
|
||||
qself: None,
|
||||
path: qual_name,
|
||||
attrs: Default::default(),
|
||||
})),
|
||||
_ => Box::new(Pat::Struct(PatStruct {
|
||||
attrs: Default::default(),
|
||||
qself: None,
|
||||
path: qual_name,
|
||||
brace_token: Default::default(),
|
||||
fields: Default::default(),
|
||||
rest: Some(PatRest {
|
||||
attrs: Default::default(),
|
||||
dot2_token: def_site(),
|
||||
}),
|
||||
})),
|
||||
};
|
||||
|
||||
Arm {
|
||||
body,
|
||||
attrs: v
|
||||
.attrs()
|
||||
.iter()
|
||||
.filter(|attr| is_attr_name(attr, "cfg"))
|
||||
.cloned()
|
||||
.collect(),
|
||||
pat: Pat::Reference(PatReference {
|
||||
and_token: def_site(),
|
||||
mutability: None,
|
||||
pat,
|
||||
attrs: Default::default(),
|
||||
}),
|
||||
guard: None,
|
||||
fat_arrow_token: def_site(),
|
||||
comma: Some(def_site()),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let body = Expr::Match(ExprMatch {
|
||||
attrs: Default::default(),
|
||||
match_token: def_site(),
|
||||
brace_token: def_site(),
|
||||
expr: Box::new(
|
||||
Quote::new(def_site::<Span>())
|
||||
.quote_with(smart_quote!(Vars {}, { self }))
|
||||
.parse(),
|
||||
),
|
||||
arms,
|
||||
});
|
||||
|
||||
Quote::new(def_site::<Span>())
|
||||
.quote_with(smart_quote!(
|
||||
Vars {
|
||||
Type: &i.ident,
|
||||
body,
|
||||
as_str: make_as_str_ident(),
|
||||
},
|
||||
{
|
||||
impl Type {
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
body
|
||||
}
|
||||
}
|
||||
}
|
||||
))
|
||||
.parse::<ItemImpl>()
|
||||
.with_generics(i.generics.clone())
|
||||
}
|
||||
|
||||
fn make_as_str_ident() -> Ident {
|
||||
Ident::new("as_str", call_site())
|
||||
}
|
||||
|
||||
fn make_serialize(i: &DeriveInput) -> ItemImpl {
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(Vars { Type: &i.ident }, {
|
||||
#[cfg(feature = "serde")]
|
||||
impl ::serde::Serialize for Type {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: ::serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.as_str())
|
||||
}
|
||||
}
|
||||
}))
|
||||
.parse::<ItemImpl>()
|
||||
.with_generics(i.generics.clone())
|
||||
}
|
||||
|
||||
fn make_deserialize(i: &DeriveInput) -> ItemImpl {
|
||||
Quote::new_call_site()
|
||||
.quote_with(smart_quote!(Vars { Type: &i.ident }, {
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> ::serde::Deserialize<'de> for Type {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: ::serde::Deserializer<'de>,
|
||||
{
|
||||
struct StrVisitor;
|
||||
|
||||
impl<'de> ::serde::de::Visitor<'de> for StrVisitor {
|
||||
type Value = Type;
|
||||
|
||||
fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
// TODO: List strings
|
||||
write!(f, "one of (TODO)")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: ::serde::de::Error,
|
||||
{
|
||||
// TODO
|
||||
value.parse().map_err(|()| E::unknown_variant(value, &[]))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(StrVisitor)
|
||||
}
|
||||
}
|
||||
}))
|
||||
.parse::<ItemImpl>()
|
||||
.with_generics(i.generics.clone())
|
||||
}
|
||||
|
||||
struct FieldAttr {
|
||||
aliases: Punctuated<FieldAttrItem, Token![,]>,
|
||||
}
|
||||
|
||||
impl Parse for FieldAttr {
|
||||
fn parse(input: parse::ParseStream) -> Result<Self> {
|
||||
Ok(Self {
|
||||
aliases: input.call(Punctuated::parse_terminated)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// `alias("text")` in `#[string_enum(alias("text"))]`.
|
||||
struct FieldAttrItem {
|
||||
alias: LitStr,
|
||||
}
|
||||
|
||||
impl Parse for FieldAttrItem {
|
||||
fn parse(input: parse::ParseStream) -> Result<Self> {
|
||||
let name: Ident = input.parse()?;
|
||||
|
||||
assert!(
|
||||
name == "alias",
|
||||
"#[derive(StringEnum) only supports `#[string_enum(alias(\"text\"))]]"
|
||||
);
|
||||
|
||||
let alias;
|
||||
parenthesized!(alias in input);
|
||||
|
||||
Ok(Self {
|
||||
alias: alias.parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
28
third-party/vendor/string_enum/tests/simple.rs
vendored
Normal file
28
third-party/vendor/string_enum/tests/simple.rs
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
use std::fmt::{Debug, Display};
|
||||
|
||||
use string_enum::*;
|
||||
|
||||
pub trait Assert: Debug + Display {}
|
||||
|
||||
#[derive(StringEnum)]
|
||||
pub enum Tokens {
|
||||
///`a`
|
||||
#[string_enum(alias("foo"))]
|
||||
A,
|
||||
/// `b`
|
||||
B,
|
||||
}
|
||||
|
||||
impl Assert for Tokens {}
|
||||
|
||||
#[test]
|
||||
fn as_str() {
|
||||
assert_eq!(Tokens::A.as_str(), "a");
|
||||
assert_eq!(Tokens::B.as_str(), "b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt() {
|
||||
assert_eq!(Tokens::A.to_string(), "a");
|
||||
assert_eq!(format!("{}", Tokens::A), "a");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue