]> git.proxmox.com Git - proxmox.git/commitdiff
rename sorted-data to proxmox-sortable_macro
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 21 Nov 2019 12:10:37 +0000 (13:10 +0100)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Thu, 21 Nov 2019 12:10:37 +0000 (13:10 +0100)
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Cargo.toml
proxmox-sortable-macro/Cargo.toml [new file with mode: 0644]
proxmox-sortable-macro/src/lib.rs [new file with mode: 0644]
proxmox-sortable-macro/tests/test.rs [new file with mode: 0644]
proxmox/Cargo.toml
proxmox/src/lib.rs
sorted-data/Cargo.toml [deleted file]
sorted-data/src/lib.rs [deleted file]
sorted-data/tests/test.rs [deleted file]

index 454b3a16651db44ce1ce1085154732e60f803e75..7a957f1b0d57caf68c73d4aa70ef7edcadf73149 100644 (file)
@@ -1,12 +1,11 @@
 [workspace]
 members = [
-    "proxmox-tools",
+    "proxmox",
     "proxmox-api",
     "proxmox-api-macro",
+    "proxmox-sortable-macro",
     "proxmox-sys",
-    "proxmox",
-
-    "sorted-data",
+    "proxmox-tools",
 
 # This is an api server test and may be temporarily broken by changes to
 # proxmox-api or proxmox-api-macro, but should ultimately be updated to work
diff --git a/proxmox-sortable-macro/Cargo.toml b/proxmox-sortable-macro/Cargo.toml
new file mode 100644 (file)
index 0000000..5aa7f8e
--- /dev/null
@@ -0,0 +1,15 @@
+[package]
+name = "proxmox-sortable-macro"
+version = "0.1.0"
+authors = ["Wolfgang Bumiller <w.bumiller@proxmox.com>"]
+edition = "2018"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+#failure = { version = "0.1", default-features = false, features = ["std"] }
+failure = "0.1"
+proc-macro2 = "1.0"
+quote = "1.0"
+syn = { version = "1.0", features = [ "full", "visit-mut" ] }
diff --git a/proxmox-sortable-macro/src/lib.rs b/proxmox-sortable-macro/src/lib.rs
new file mode 100644 (file)
index 0000000..699f3fd
--- /dev/null
@@ -0,0 +1,116 @@
+extern crate proc_macro;
+extern crate proc_macro2;
+
+use std::iter::FromIterator;
+use std::mem;
+
+use failure::Error;
+
+use proc_macro::TokenStream as TokenStream_1;
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::punctuated::Punctuated;
+use syn::spanned::Spanned;
+use syn::visit_mut::VisitMut;
+use syn::Ident;
+
+macro_rules! format_err {
+    ($span:expr => $($msg:tt)*) => { syn::Error::new_spanned($span, format!($($msg)*)) };
+    ($span:expr, $($msg:tt)*) => { syn::Error::new($span, format!($($msg)*)) };
+}
+
+//macro_rules! bail {
+//    ($span:expr => $($msg:tt)*) => { return Err(format_err!($span => $($msg)*).into()) };
+//    ($span:expr, $($msg:tt)*) => { return Err(format_err!($span, $($msg)*).into()) };
+//}
+
+fn handle_error(data: Result<TokenStream, Error>) -> TokenStream {
+    match data {
+        Ok(output) => output,
+        Err(err) => match err.downcast::<syn::Error>() {
+            Ok(err) => err.to_compile_error(),
+            Err(err) => panic!("error in sorted_struct macro: {}", err),
+        },
+    }
+}
+
+/// Enable the `sorted!` expression-position macro in a statement.
+#[proc_macro_attribute]
+pub fn sortable(_attr: TokenStream_1, item: TokenStream_1) -> TokenStream_1 {
+    handle_error(sortable_do(item.into())).into()
+}
+
+struct SortedData;
+
+impl VisitMut for SortedData {
+    fn visit_expr_macro_mut(&mut self, i: &mut syn::ExprMacro) {
+        if i.mac.path.is_ident("sorted") {
+            let span = i.mac.path.span();
+            i.mac.path.segments = Punctuated::new();
+            i.mac.path.segments.push(syn::PathSegment {
+                ident: Ident::new("identity", span),
+                arguments: Default::default(),
+            });
+
+            let tokens = mem::replace(&mut i.mac.tokens, TokenStream::new());
+            i.mac.tokens = handle_error(sort_data(tokens));
+        }
+        // and recurse:
+        self.visit_macro_mut(&mut i.mac)
+    }
+}
+
+fn sortable_do(item: TokenStream) -> Result<TokenStream, Error> {
+    let mut item: syn::Item = syn::parse2(item)?;
+    SortedData.visit_item_mut(&mut item);
+    Ok(quote!(#item))
+}
+
+fn sort_data(data: TokenStream) -> Result<TokenStream, Error> {
+    let mut array: syn::ExprArray = syn::parse2(data)?;
+    let span = array.span();
+
+    let mut fields: Vec<syn::Expr> = mem::replace(&mut array.elems, Punctuated::new())
+        .into_iter()
+        .collect();
+
+    let mut err = None;
+    fields.sort_by(|a, b| {
+        if err.is_some() {
+            return std::cmp::Ordering::Equal;
+        }
+
+        use syn::{Expr, Lit};
+        match (a, b) {
+            // We can sort an array of literals:
+            (Expr::Lit(a), Expr::Lit(b)) => match (&a.lit, &b.lit) {
+                (Lit::Str(a), Lit::Str(b)) => return a.value().cmp(&b.value()),
+                _ => err = Some(format_err!(span, "can only sort by string literals!")),
+            },
+
+            // We can sort an array of tuples where the first element is a literal:
+            (Expr::Tuple(a), Expr::Tuple(b)) => match (a.elems.first(), b.elems.first()) {
+                (Some(Expr::Lit(a)), Some(Expr::Lit(b))) => match (&a.lit, &b.lit) {
+                    (Lit::Str(a), Lit::Str(b)) => return a.value().cmp(&b.value()),
+                    _ => err = Some(format_err!(span, "can only sort by string literals!")),
+                },
+                _ => {
+                    err = Some(format_err!(
+                        span,
+                        "can only sort tuples starting with literals!"
+                    ))
+                }
+            },
+            _ => err = Some(format_err!(span, "don't know how to sort this data!")),
+        }
+        std::cmp::Ordering::Equal
+    });
+
+    if let Some(err) = err {
+        return Err(err.into());
+    }
+
+    array.elems = Punctuated::from_iter(fields);
+
+    Ok(quote!(#array))
+}
diff --git a/proxmox-sortable-macro/tests/test.rs b/proxmox-sortable-macro/tests/test.rs
new file mode 100644 (file)
index 0000000..f1eb463
--- /dev/null
@@ -0,0 +1,28 @@
+use proxmox_sortable_macro::sortable;
+
+// The way #[sorted] works we require an 'identity' macro due to the inability of the syntax tree
+// visitor to change the type of a syntax tree element.
+//
+// Iow.: it replaces `sorted!([3, 2, 1])` with `identity!([1, 2, 3])`.
+macro_rules! identity {
+    ($($x:tt)*) => { $($x)* }
+}
+
+// In a normal project we would use this Cargo.toml line:
+//
+// [dependencies]
+// proxmox = { version = "0.1", features = [ "sortable-macro" ] }
+//
+// Then:
+// use proxmox::{sortable, identity};
+
+#[test]
+fn test_id() {
+    #[sortable]
+    const FOO: [&str; 3] = sorted!(["3", "2", "1"]);
+    assert_eq!(FOO, ["1", "2", "3"]);
+
+    #[sortable]
+    const FOO2: [(&str, usize); 3] = sorted!([("3", 1), ("2", 2), ("1", 3)]);
+    assert_eq!(FOO2, [("1", 3), ("2", 2), ("3", 1)]);
+}
index a295a4082b62e146e2cbe37ca52f7e0a92546bdf..7d92a4e5a67dd1ac4673dbd8b087320aa58ced33 100644 (file)
@@ -12,10 +12,10 @@ proxmox-api = { path = "../proxmox-api" }
 proxmox-api-macro = { path = "../proxmox-api-macro", optional = true }
 proxmox-sys = { path = "../proxmox-sys" }
 proxmox-tools = { path = "../proxmox-tools" }
-sorted-data = { path = "../sorted-data", optional = true }
+proxmox-sortable-macro = { path = "../proxmox-sortable-macro", optional = true }
 
 [features]
 default = []
 valgrind = ["proxmox-tools/valgrind"]
 api-macro = ["proxmox-api-macro"]
-sortable-macro = ["sorted-data"]
+sortable-macro = ["proxmox-sortable-macro"]
index 0f7a8e3df093270bf287c12a2c29fecd5ab9a4d5..1248a299ef627aace92810ef67ed2aac4227a742 100644 (file)
@@ -11,5 +11,9 @@ pub mod api {
 
 #[cfg(feature = "sortable-macro")]
 pub use proxmox_tools::identity;
+
+#[cfg(feature = "sortable-macro")]
+pub use proxmox_sortable_macro as sortable_macro;
+
 #[cfg(feature = "sortable-macro")]
-pub use sorted_data::{self, sortable};
+pub use proxmox_sortable_macro::sortable;
diff --git a/sorted-data/Cargo.toml b/sorted-data/Cargo.toml
deleted file mode 100644 (file)
index 5dff0ed..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "sorted-data"
-version = "0.1.0"
-authors = ["Wolfgang Bumiller <w.bumiller@proxmox.com>"]
-edition = "2018"
-
-[lib]
-proc-macro = true
-
-[dependencies]
-#failure = { version = "0.1", default-features = false, features = ["std"] }
-failure = "0.1"
-proc-macro2 = "1.0"
-quote = "1.0"
-syn = { version = "1.0", features = [ "full", "visit-mut" ] }
diff --git a/sorted-data/src/lib.rs b/sorted-data/src/lib.rs
deleted file mode 100644 (file)
index 699f3fd..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-extern crate proc_macro;
-extern crate proc_macro2;
-
-use std::iter::FromIterator;
-use std::mem;
-
-use failure::Error;
-
-use proc_macro::TokenStream as TokenStream_1;
-use proc_macro2::TokenStream;
-use quote::quote;
-use syn::punctuated::Punctuated;
-use syn::spanned::Spanned;
-use syn::visit_mut::VisitMut;
-use syn::Ident;
-
-macro_rules! format_err {
-    ($span:expr => $($msg:tt)*) => { syn::Error::new_spanned($span, format!($($msg)*)) };
-    ($span:expr, $($msg:tt)*) => { syn::Error::new($span, format!($($msg)*)) };
-}
-
-//macro_rules! bail {
-//    ($span:expr => $($msg:tt)*) => { return Err(format_err!($span => $($msg)*).into()) };
-//    ($span:expr, $($msg:tt)*) => { return Err(format_err!($span, $($msg)*).into()) };
-//}
-
-fn handle_error(data: Result<TokenStream, Error>) -> TokenStream {
-    match data {
-        Ok(output) => output,
-        Err(err) => match err.downcast::<syn::Error>() {
-            Ok(err) => err.to_compile_error(),
-            Err(err) => panic!("error in sorted_struct macro: {}", err),
-        },
-    }
-}
-
-/// Enable the `sorted!` expression-position macro in a statement.
-#[proc_macro_attribute]
-pub fn sortable(_attr: TokenStream_1, item: TokenStream_1) -> TokenStream_1 {
-    handle_error(sortable_do(item.into())).into()
-}
-
-struct SortedData;
-
-impl VisitMut for SortedData {
-    fn visit_expr_macro_mut(&mut self, i: &mut syn::ExprMacro) {
-        if i.mac.path.is_ident("sorted") {
-            let span = i.mac.path.span();
-            i.mac.path.segments = Punctuated::new();
-            i.mac.path.segments.push(syn::PathSegment {
-                ident: Ident::new("identity", span),
-                arguments: Default::default(),
-            });
-
-            let tokens = mem::replace(&mut i.mac.tokens, TokenStream::new());
-            i.mac.tokens = handle_error(sort_data(tokens));
-        }
-        // and recurse:
-        self.visit_macro_mut(&mut i.mac)
-    }
-}
-
-fn sortable_do(item: TokenStream) -> Result<TokenStream, Error> {
-    let mut item: syn::Item = syn::parse2(item)?;
-    SortedData.visit_item_mut(&mut item);
-    Ok(quote!(#item))
-}
-
-fn sort_data(data: TokenStream) -> Result<TokenStream, Error> {
-    let mut array: syn::ExprArray = syn::parse2(data)?;
-    let span = array.span();
-
-    let mut fields: Vec<syn::Expr> = mem::replace(&mut array.elems, Punctuated::new())
-        .into_iter()
-        .collect();
-
-    let mut err = None;
-    fields.sort_by(|a, b| {
-        if err.is_some() {
-            return std::cmp::Ordering::Equal;
-        }
-
-        use syn::{Expr, Lit};
-        match (a, b) {
-            // We can sort an array of literals:
-            (Expr::Lit(a), Expr::Lit(b)) => match (&a.lit, &b.lit) {
-                (Lit::Str(a), Lit::Str(b)) => return a.value().cmp(&b.value()),
-                _ => err = Some(format_err!(span, "can only sort by string literals!")),
-            },
-
-            // We can sort an array of tuples where the first element is a literal:
-            (Expr::Tuple(a), Expr::Tuple(b)) => match (a.elems.first(), b.elems.first()) {
-                (Some(Expr::Lit(a)), Some(Expr::Lit(b))) => match (&a.lit, &b.lit) {
-                    (Lit::Str(a), Lit::Str(b)) => return a.value().cmp(&b.value()),
-                    _ => err = Some(format_err!(span, "can only sort by string literals!")),
-                },
-                _ => {
-                    err = Some(format_err!(
-                        span,
-                        "can only sort tuples starting with literals!"
-                    ))
-                }
-            },
-            _ => err = Some(format_err!(span, "don't know how to sort this data!")),
-        }
-        std::cmp::Ordering::Equal
-    });
-
-    if let Some(err) = err {
-        return Err(err.into());
-    }
-
-    array.elems = Punctuated::from_iter(fields);
-
-    Ok(quote!(#array))
-}
diff --git a/sorted-data/tests/test.rs b/sorted-data/tests/test.rs
deleted file mode 100644 (file)
index ea3f9e3..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-use sorted_data::sortable;
-
-// The way #[sorted] works we require an 'identity' macro due to the inability of the syntax tree
-// visitor to change the type of a syntax tree element.
-//
-// Iow.: it replaces `sorted!([3, 2, 1])` with `identity!([1, 2, 3])`.
-macro_rules! identity {
-    ($($x:tt)*) => { $($x)* }
-}
-
-// In a normal project we would use this Cargo.toml line:
-//
-// [dependencies]
-// proxmox = { version = "0.1", features = [ "sortable-macro" ] }
-//
-// Then:
-// use proxmox::{sortable, identity};
-
-#[test]
-fn test_id() {
-    #[sortable]
-    const FOO: [&str; 3] = sorted!(["3", "2", "1"]);
-    assert_eq!(FOO, ["1", "2", "3"]);
-
-    #[sortable]
-    const FOO2: [(&str, usize); 3] = sorted!([("3", 1), ("2", 2), ("1", 3)]);
-    assert_eq!(FOO2, [("1", 3), ("2", 2), ("3", 1)]);
-}