Skip to content

Commit

Permalink
More passing tests (but more errors)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsafMah committed Jan 2, 2024
1 parent 2cceb8d commit 1b36dcb
Show file tree
Hide file tree
Showing 11 changed files with 282 additions and 145 deletions.
4 changes: 2 additions & 2 deletions azure-kusto-data/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ time = { version = "0.3", features = [
derive_builder = "0.12"
derive_more = { version = "1.0.0-beta.6" , features = ["from", "into", "display", "from_str"] }
once_cell = "1"
rust_decimal = { version = "1.33.1", features = ["serde-str"] }
uuid = { version = "1.3.0", features = ["serde"] }

[dev-dependencies]
arrow = { version = "49.0.0", features = ["prettyprint"] }
Expand All @@ -49,8 +51,6 @@ tokio = { version = "1.25.0", features = ["macros"] }
oauth2 = "4.3.0"
criterion = "0.5"
clap = { version = "4.1.6", features = ["derive", "env"] }
decimal = "2.1.0"
uuid = { version = "1.3.0", features = ["serde"] }

[features]
default = ["arrow"]
Expand Down
50 changes: 25 additions & 25 deletions azure-kusto-data/examples/query.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use azure_kusto_data::models::V2QueryResult;
use azure_kusto_data::prelude::*;
use azure_kusto_data::types::timespan::{KustoDateTime, KustoTimespan};
use clap::Parser;
use futures::{pin_mut, TryStreamExt};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::error::Error;
use azure_kusto_data::{KustoBool, KustoDateTime, KustoDecimal, KustoDynamic, KustoGuid, KustoInt, KustoLong, KustoReal, KustoString, KustoTimespan};
use azure_kusto_data::models::v2::Frame;

/// Simple program to greet a person
#[derive(Parser, Debug, Clone)]
Expand Down Expand Up @@ -78,15 +78,15 @@ async fn progressive(args: &Args, client: &KustoClient) -> Result<(), Box<dyn Er

while let Some(table) = stream.try_next().await? {
match table {
V2QueryResult::DataSetHeader(header) => println!("header: {:#?}", header),
V2QueryResult::DataTable(table) => println!("table: {:#?}", table),
V2QueryResult::DataSetCompletion(completion) => {
Frame::DataSetHeader(header) => println!("header: {:#?}", header),
Frame::DataTable(table) => println!("table: {:#?}", table),
Frame::DataSetCompletion(completion) => {
println!("completion: {:#?}", completion)
}
V2QueryResult::TableHeader(header) => println!("header: {:#?}", header),
V2QueryResult::TableFragment(fragment) => println!("fragment: {:#?}", fragment),
V2QueryResult::TableProgress(progress) => println!("progress: {:#?}", progress),
V2QueryResult::TableCompletion(completion) => {
Frame::TableHeader(header) => println!("header: {:#?}", header),
Frame::TableFragment(fragment) => println!("fragment: {:#?}", fragment),
Frame::TableProgress(progress) => println!("progress: {:#?}", progress),
Frame::TableCompletion(completion) => {
println!("completion: {:#?}", completion)
}
}
Expand Down Expand Up @@ -116,15 +116,15 @@ async fn non_progressive(args: &Args, client: &KustoClient) {

for table in &response.results {
match table {
V2QueryResult::DataSetHeader(header) => println!("header: {:#?}", header),
V2QueryResult::DataTable(table) => println!("table: {:#?}", table),
V2QueryResult::DataSetCompletion(completion) => {
Frame::DataSetHeader(header) => println!("header: {:#?}", header),
Frame::DataTable(table) => println!("table: {:#?}", table),
Frame::DataSetCompletion(completion) => {
println!("completion: {:#?}", completion)
}
V2QueryResult::TableHeader(header) => println!("header: {:#?}", header),
V2QueryResult::TableFragment(fragment) => println!("fragment: {:#?}", fragment),
V2QueryResult::TableProgress(progress) => println!("progress: {:#?}", progress),
V2QueryResult::TableCompletion(completion) => {
Frame::TableHeader(header) => println!("header: {:#?}", header),
Frame::TableFragment(fragment) => println!("fragment: {:#?}", fragment),
Frame::TableProgress(progress) => println!("progress: {:#?}", progress),
Frame::TableCompletion(completion) => {
println!("completion: {:#?}", completion)
}
}
Expand All @@ -137,16 +137,16 @@ async fn non_progressive(args: &Args, client: &KustoClient) {

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
struct Item {
vnum: i32,
vdec: String, // optionally, you can use a decimal type here
vnum: KustoInt,
vdec: KustoDecimal,
vdate: KustoDateTime,
vspan: KustoTimespan,
vobj: Value,
vb: bool,
vreal: f64,
vstr: String,
vlong: i64,
vguid: String, // optionally, you can use a guid type here
vobj: KustoDynamic,
vb: KustoBool,
vreal: KustoReal,
vstr: KustoString,
vlong: KustoLong,
vguid: KustoGuid
}

async fn to_struct(args: &Args, client: &KustoClient) -> Result<(), Box<dyn Error>> {
Expand All @@ -172,7 +172,7 @@ async fn to_struct(args: &Args, client: &KustoClient) -> Result<(), Box<dyn Erro
.next()
.ok_or_else(|| "Expected to get a primary result, but got none".to_string())?;

let rows = results.rows;
let rows = results.rows.into_iter().map(|r| Value::Array(r.into_result().unwrap())).collect::<Vec<_>>();

let items = serde_json::from_value::<Vec<Item>>(Value::Array(rows))?;

Expand Down
7 changes: 4 additions & 3 deletions azure-kusto-data/src/arrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::error::Result;
use crate::models::v2::{Column, DataTable};
use crate::models::ColumnType;
use crate::models::v2::Row::Values;
use crate::types::{KustoDateTime, Timespan};
use crate::types::{KustoDateTime, KustoTimespan};

fn convert_array_string(values: Vec<Value>) -> Result<ArrayRef> {

Check warning on line 17 in azure-kusto-data/src/arrow.rs

View workflow job for this annotation

GitHub Actions / clippy

the `Err`-variant returned from this function is very large

warning: the `Err`-variant returned from this function is very large --> azure-kusto-data/src/arrow.rs:17:48 | 17 | fn convert_array_string(values: Vec<Value>) -> Result<ArrayRef> { | ^^^^^^^^^^^^^^^^ | ::: azure-kusto-data/src/error.rs:56:5 | 56 | QueryApiError(OneApiError), | -------------------------- the largest variant contains at least 328 bytes | = help: try reducing the size of `error::Error`, for example by boxing large elements or replacing it with `Box<error::Error>` = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err = note: `#[warn(clippy::result_large_err)]` on by default
let strings: Vec<Option<String>> = serde_json::from_value(Value::Array(values))?;
Expand Down Expand Up @@ -57,9 +57,10 @@ fn convert_array_timespan(values: Vec<Value>) -> Result<ArrayRef> {
let durations: Vec<Option<i64>> = strings
.iter()
.map(|s| {
s.parse::<Timespan>()
s.parse::<KustoTimespan>()
.ok()
.and_then(|d| i64::try_from(d.0.whole_nanoseconds()).ok())
.and_then(|d| d.0)
.and_then(|d| i64::try_from(d.whole_nanoseconds()).ok())
})
.collect();
Ok(Arc::new(DurationNanosecondArray::from(durations)))
Expand Down
6 changes: 4 additions & 2 deletions azure-kusto-data/src/authorization_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ impl Policy for AuthorizationPolicy {
}
};

let token = cred.get_token(&[".default"]).await?;
let scope = format!("{}/.default", resource);

request.insert_header(AUTHORIZATION, &format!("Bearer {}", dbg!(token.token.secret())));
let token = cred.get_token(&[&scope]).await?;

request.insert_header(AUTHORIZATION, &format!("Bearer {}", token.token.secret()));

next[0].send(ctx, request, &next[1..]).await
}
Expand Down
3 changes: 1 addition & 2 deletions azure-kusto-data/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use std::fmt::Debug;

use thiserror;
use crate::models::v2::OneApiError;

/// Error type for kusto operations.
#[derive(thiserror::Error, Debug)]
pub enum Error {
Expand Down Expand Up @@ -74,7 +73,7 @@ pub enum ParseError {
#[error("Error parsing guid: {0}")]
Guid(#[from] uuid::Error),

Check warning on line 74 in azure-kusto-data/src/error.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> azure-kusto-data/src/error.rs:74:5 | 74 | Guid(#[from] uuid::Error), | ^^^^
#[error("Error parsing decimal")]
Decimal(()),
Decimal(#[from] rust_decimal::Error),

Check warning on line 76 in azure-kusto-data/src/error.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> azure-kusto-data/src/error.rs:76:5 | 76 | Decimal(#[from] rust_decimal::Error), | ^^^^^^^
#[error("Error parsing dynamic: {0}")]
Dynamic(#[from] serde_json::Error),

Check warning on line 78 in azure-kusto-data/src/error.rs

View workflow job for this annotation

GitHub Actions / clippy

missing documentation for a variant

warning: missing documentation for a variant --> azure-kusto-data/src/error.rs:78:5 | 78 | Dynamic(#[from] serde_json::Error), | ^^^^^^^
}
Expand Down
2 changes: 2 additions & 0 deletions azure-kusto-data/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ pub mod prelude;
mod query;
pub mod request_options;
pub mod types;

pub use types::*;
1 change: 0 additions & 1 deletion azure-kusto-data/src/models/v2/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use serde::{Deserialize, Serialize};

/// Where errors are reported - within the data, at the end of the table, or at the end of the dataset.
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
#[serde(rename_all = "snake_case")]
pub enum ErrorReportingPlacement {
/// Errors are reported within the data.
InData,
Expand Down
68 changes: 68 additions & 0 deletions azure-kusto-data/src/types/datetime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::fmt::Display;
use std::str::FromStr;
use derive_more::{From, Into};
use serde::{Deserialize, Serialize};
use time::{OffsetDateTime};
use time::format_description::well_known::Rfc3339;
use crate::error::{Error, ParseError};

/// Datetime for kusto, for serialization and deserialization.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Into, Debug)]
pub struct KustoDateTime(pub Option<OffsetDateTime>);

impl KustoDateTime {
/// Creates a new `KustoDatetime` from a `time::OffsetDateTime`.
pub fn new(value: OffsetDateTime) -> Self {
Self(Some(value))
}

/// Creates a null `KustoDatetime`.
pub fn null() -> Self {
Self(None)
}
}

impl Display for KustoDateTime {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.0 {
Some(v) => write!(f, "KustoDateTime({})", v),
None => write!(f, "null"),
}
}
}

impl Serialize for KustoDateTime {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match &self.0 {
Some(v) => serializer.serialize_str(&v.format(&Rfc3339).expect("Should never fail")),
None => serializer.serialize_none(),
}
}
}

impl<'de> Deserialize<'de> for KustoDateTime {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let opt = Option::<String>::deserialize(deserializer)?;
if let Some(s) = opt {
Ok(s.parse::<KustoDateTime>().map_err(|e| serde::de::Error::custom(e.to_string()))?)
} else {
Ok(Self::null())
}
}
}

impl FromStr for KustoDateTime {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new(OffsetDateTime::parse(s, &Rfc3339).map_err(
|e| Error::from(ParseError::DateTime(e)))?
))
}
}

impl From<OffsetDateTime> for KustoDateTime {
fn from(v: OffsetDateTime) -> Self {
Self::new(v)
}
}
47 changes: 17 additions & 30 deletions azure-kusto-data/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,32 @@ use std::convert::Infallible;
use derive_more::{Display, From, Into, FromStr};
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;
use rust_decimal::Decimal;
use crate::error::{Error, ParseError};
pub use crate::types::timespan::Timespan;

mod timespan;
mod datetime;

macro_rules! kusto_type {
($name:ident, $type:ty, primitive) => {
kusto_type!($name, $type, Copy, PartialEq, PartialOrd, Eq, Ord);
kusto_type!($name, $type, Copy, PartialOrd, Eq, Ord);
};
($name:ident, $type:ty, $($additional:tt),* ) => {
#[doc = concat!("Represents a ", stringify!($type), " for kusto, for serialization and deserialization.")]
#[derive(Deserialize, Serialize, Default, Clone, From, Into, Debug, $($additional),*)]
#[derive(Deserialize, Serialize, Default, Clone, From, Into, Debug, PartialEq, $($additional),*)]
#[serde(transparent)]
pub struct $name(pub Option<$type>);

impl $name {
#[doc = concat!("Creates a new ", stringify!($type), " for kusto.")]
pub fn new(value: $type) -> Self {
Self(Some(value))
}

#[doc = concat!("Creates a null ", stringify!($type), " for kusto.")]
pub fn null() -> Self {
Self(None)
}
}

impl Display for $name {
Expand Down Expand Up @@ -72,39 +77,21 @@ macro_rules! kusto_from_str {
kusto_type!(KustoBool, bool, primitive);
kusto_type!(KustoInt, i32, primitive);
kusto_type!(KustoLong, i64, primitive);
kusto_type!(KustoReal, f64, Copy, PartialEq, PartialOrd);
kusto_type!(KustoDecimal, decimal::d128, Copy);
kusto_type!(KustoString, String, PartialEq, PartialOrd, Eq, Ord);
kusto_type!(KustoDynamic, serde_json::Value, PartialEq, Eq);
kusto_type!(KustoReal, f64, Copy, PartialOrd);
kusto_type!(KustoDecimal, Decimal, primitive);
kusto_type!(KustoString, String, PartialOrd, Eq, Ord);
kusto_type!(KustoDynamic, serde_json::Value, Eq);
kusto_type!(KustoGuid, uuid::Uuid, primitive);
kusto_type!(KustoDateTime, OffsetDateTime, primitive);
kusto_type!(KustoTimespan, Timespan, primitive);

pub use datetime::KustoDateTime;
pub use timespan::KustoTimespan;

kusto_from_str!(KustoBool, bool, ParseError::Bool);
kusto_from_str!(KustoInt, i32, ParseError::Int);
kusto_from_str!(KustoLong, i64, ParseError::Int);
kusto_from_str!(KustoReal, f64, ParseError::Float);
kusto_from_str!(KustoDecimal, decimal::d128, ParseError::Decimal);
kusto_from_str!(KustoDecimal, Decimal, ParseError::Decimal);
kusto_from_str!(KustoGuid, uuid::Uuid, ParseError::Guid);

impl FromStr for KustoDateTime {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new(OffsetDateTime::parse(s, &Rfc3339).map_err(
|e| Error::from(ParseError::DateTime(e)))?
))
}
}

impl FromStr for KustoTimespan {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::new(s.parse::<Timespan>()?))
}
}

impl FromStr for KustoString {
type Err = Infallible;
Expand Down
Loading

0 comments on commit 1b36dcb

Please sign in to comment.