Skip to content

Commit 614316a

Browse files
authored
implement #[influxdb(tag)] and #[influxdb(ignore)] (#81)
* first failed attempt to implement #[influx_aware()] * change influx_aware to influxdb * remove clone * remove references to #[tag] * add missing field * fix test_write_and_read_option * handle ignore field in deserialized struct
1 parent 5ed1347 commit 614316a

File tree

6 files changed

+77
-19
lines changed

6 files changed

+77
-19
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ async fn main() {
7171
struct WeatherReading {
7272
time: DateTime<Utc>,
7373
humidity: i32,
74-
#[tag] wind_direction: String,
74+
#[influxdb(tag)] wind_direction: String,
7575
}
7676

7777
// Let's write some data into a measurement called `weather`

benches/client.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use tokio::sync::Semaphore;
1111
struct WeatherReading {
1212
time: DateTime<Utc>,
1313
humidity: i32,
14-
#[tag]
14+
#[influxdb(tag)]
1515
wind_direction: String,
1616
}
1717

influxdb/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
//! struct WeatherReading {
4040
//! time: DateTime<Utc>,
4141
//! humidity: i32,
42-
//! #[tag] wind_direction: String,
42+
//! #[influxdb(tag)] wind_direction: String,
4343
//! }
4444
//!
4545
//! // Let's write some data into a measurement called `weather`

influxdb/tests/derive_integration_tests.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,20 @@ use utilities::{assert_result_ok, create_client, create_db, delete_db, run_test}
1414

1515
#[derive(Debug, PartialEq)]
1616
#[cfg_attr(feature = "derive", derive(InfluxDbWriteable))]
17-
#[cfg_attr(feature = "use-serde", derive(Deserialize))]
1817
struct WeatherReading {
1918
time: DateTime<Utc>,
19+
#[influxdb(ignore)]
2020
humidity: i32,
21-
#[tag]
21+
pressure: i32,
22+
#[influxdb(tag)]
23+
wind_strength: Option<u64>,
24+
}
25+
26+
#[derive(Debug)]
27+
#[cfg_attr(feature = "use-serde", derive(Deserialize))]
28+
struct WeatherReadingWithoutIgnored {
29+
time: DateTime<Utc>,
30+
pressure: i32,
2231
wind_strength: Option<u64>,
2332
}
2433

@@ -27,15 +36,14 @@ fn test_build_query() {
2736
let weather_reading = WeatherReading {
2837
time: Timestamp::Hours(1).into(),
2938
humidity: 30,
39+
pressure: 100,
3040
wind_strength: Some(5),
3141
};
32-
let query = weather_reading
33-
.into_query("weather_reading")
34-
.build()
35-
.unwrap();
42+
let query = weather_reading.into_query("weather_reading");
43+
let query = query.build().unwrap();
3644
assert_eq!(
3745
query.get(),
38-
"weather_reading,wind_strength=5 humidity=30i 3600000000000"
46+
"weather_reading,wind_strength=5 pressure=100i 3600000000000"
3947
);
4048
}
4149

@@ -56,6 +64,7 @@ async fn test_derive_simple_write() {
5664
time: Timestamp::Nanoseconds(0).into(),
5765
humidity: 30,
5866
wind_strength: Some(5),
67+
pressure: 100,
5968
};
6069
let query = weather_reading.into_query("weather_reading");
6170
let result = client.query(&query).await;
@@ -86,20 +95,21 @@ async fn test_write_and_read_option() {
8695
time: Timestamp::Hours(11).into(),
8796
humidity: 30,
8897
wind_strength: None,
98+
pressure: 100,
8999
};
90100
let write_result = client
91101
.query(&weather_reading.into_query("weather_reading".to_string()))
92102
.await;
93103
assert_result_ok(&write_result);
94104
let query =
95-
Query::raw_read_query("SELECT time, humidity, wind_strength FROM weather_reading");
105+
Query::raw_read_query("SELECT time, pressure, wind_strength FROM weather_reading");
96106
let result = client.json_query(query).await.and_then(|mut db_result| {
97107
println!("{:?}", db_result);
98-
db_result.deserialize_next::<WeatherReading>()
108+
db_result.deserialize_next::<WeatherReadingWithoutIgnored>()
99109
});
100110
assert_result_ok(&result);
101111
let result = result.unwrap();
102-
assert_eq!(result.series[0].values[0].humidity, 30);
112+
assert_eq!(result.series[0].values[0].pressure, 100);
103113
assert_eq!(result.series[0].values[0].wind_strength, None);
104114
},
105115
|| async move {

influxdb_derive/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fn krate() -> TokenStream2 {
99
quote!(::influxdb)
1010
}
1111

12-
#[proc_macro_derive(InfluxDbWriteable, attributes(tag))]
12+
#[proc_macro_derive(InfluxDbWriteable, attributes(influxdb))]
1313
pub fn derive_writeable(tokens: TokenStream) -> TokenStream {
1414
expand_writeable(tokens)
1515
}

influxdb_derive/src/writeable.rs

+53-5
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,79 @@
11
use proc_macro::TokenStream;
2-
use proc_macro2::TokenStream as TokenStream2;
2+
use proc_macro2::{TokenStream as TokenStream2, TokenTree};
33
use quote::{format_ident, quote};
44
use syn::{parse_macro_input, Field, Fields, Ident, ItemStruct};
55

6+
#[derive(Debug)]
67
struct WriteableField {
78
ident: Ident,
89
is_tag: bool,
10+
is_ignore: bool,
911
}
1012

1113
impl From<Field> for WriteableField {
1214
fn from(field: Field) -> WriteableField {
1315
let ident = field.ident.expect("fields without ident are not supported");
14-
let is_tag = field.attrs.iter().any(|attr| {
16+
17+
let check_influx_aware = |attr: &syn::Attribute| -> bool {
1518
attr.path
1619
.segments
1720
.iter()
1821
.last()
1922
.map(|seg| seg.ident.to_string())
2023
.unwrap_or_default()
21-
== "tag"
24+
== "influxdb"
25+
};
26+
27+
let check_for_attr = |token_tree, ident_cmp: &str| -> bool {
28+
match token_tree {
29+
TokenTree::Group(group) => group
30+
.stream()
31+
.into_iter()
32+
.next()
33+
.map(|token_tree| match token_tree {
34+
TokenTree::Ident(ident) => ident == ident_cmp,
35+
_ => false,
36+
})
37+
.unwrap(),
38+
_ => false,
39+
}
40+
};
41+
42+
let is_ignore = field.attrs.iter().any(|attr| {
43+
if !check_influx_aware(attr) {
44+
return false;
45+
}
46+
47+
attr.tokens
48+
.clone()
49+
.into_iter()
50+
.next()
51+
.map(|token_tree| check_for_attr(token_tree, "ignore"))
52+
.unwrap()
2253
});
23-
WriteableField { ident, is_tag }
54+
55+
let is_tag = field.attrs.iter().any(|attr| {
56+
if !check_influx_aware(attr) {
57+
return false;
58+
}
59+
attr.tokens
60+
.clone()
61+
.into_iter()
62+
.next()
63+
.map(|token_tree| check_for_attr(token_tree, "tag"))
64+
.unwrap()
65+
});
66+
67+
WriteableField {
68+
ident,
69+
is_tag,
70+
is_ignore,
71+
}
2472
}
2573
}
2674

2775
pub fn expand_writeable(tokens: TokenStream) -> TokenStream {
2876
let krate = super::krate();
29-
3077
let input = parse_macro_input!(tokens as ItemStruct);
3178
let ident = input.ident;
3279
let generics = input.generics;
@@ -38,6 +85,7 @@ pub fn expand_writeable(tokens: TokenStream) -> TokenStream {
3885
.named
3986
.into_iter()
4087
.map(WriteableField::from)
88+
.filter(|field| !field.is_ignore)
4189
.filter(|field| field.ident.to_string() != time_field.to_string())
4290
.map(|field| {
4391
let ident = field.ident;

0 commit comments

Comments
 (0)