From 4f615b08fadb4bec077c226faa06e98689725e49 Mon Sep 17 00:00:00 2001 From: Hanif Ariffin Date: Mon, 18 Oct 2021 22:52:56 +0800 Subject: [PATCH] chore: add rustfmt --- .github/workflows/synth-test.yml | 21 +- CONTRIBUTING.md | 7 +- core/src/compile/address.rs | 2 +- core/src/compile/link.rs | 58 ++-- core/src/compile/mod.rs | 126 ++++++--- core/src/compile/state.rs | 72 +++-- core/src/graph/array.rs | 3 +- core/src/graph/date_time.rs | 13 +- core/src/graph/json.rs | 8 +- core/src/graph/mod.rs | 252 ++++++++++-------- core/src/graph/number.rs | 34 +-- core/src/graph/object.rs | 13 +- core/src/graph/prelude.rs | 2 +- core/src/graph/string/format.rs | 5 +- core/src/graph/unique.rs | 4 +- core/src/lib.rs | 6 +- core/src/schema/content/array.rs | 7 +- core/src/schema/content/categorical.rs | 3 +- core/src/schema/content/date_time.rs | 17 +- core/src/schema/content/hidden.rs | 1 - core/src/schema/content/mod.rs | 38 ++- core/src/schema/content/number.rs | 55 ++-- core/src/schema/content/object.rs | 8 +- core/src/schema/content/string.rs | 11 +- core/src/schema/inference/mod.rs | 44 +-- core/src/schema/namespace.rs | 2 +- gen/src/error.rs | 2 +- gen/src/generator/try.rs | 14 +- gen/src/prelude.rs | 4 +- rustfmt.toml | 1 + synth/benches/bench.rs | 2 +- synth/src/cli/config.rs | 7 +- synth/src/cli/db_utils.rs | 4 +- synth/src/cli/export.rs | 24 +- synth/src/cli/import.rs | 39 ++- synth/src/cli/import_utils.rs | 14 +- synth/src/cli/mod.rs | 78 +++--- synth/src/cli/mongo.rs | 42 ++- synth/src/cli/postgres.rs | 10 +- synth/src/cli/telemetry.rs | 59 ++-- synth/src/datasource/mysql_datasource.rs | 11 +- synth/src/datasource/postgres_datasource.rs | 31 ++- synth/src/datasource/relational_datasource.rs | 28 +- synth/src/lib.rs | 8 +- synth/src/main.rs | 4 +- synth/src/sampler.rs | 60 +++-- synth/src/version.rs | 19 +- tools/hooks/pre-commit | 23 ++ 48 files changed, 766 insertions(+), 530 deletions(-) create mode 100644 rustfmt.toml create mode 100755 tools/hooks/pre-commit diff --git a/.github/workflows/synth-test.yml b/.github/workflows/synth-test.yml index 6b72c1bc..8090d7b6 100644 --- a/.github/workflows/synth-test.yml +++ b/.github/workflows/synth-test.yml @@ -2,11 +2,11 @@ name: synth-cargo-test on: push: - branches: [ master ] - paths: [ '**/*.rs' ] + branches: [master] + paths: ["**/*.rs"] pull_request: - branches: [ master ] - paths: [ '**/*.rs' ] + branches: [master] + paths: ["**/*.rs"] workflow_dispatch: @@ -15,7 +15,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ ubuntu-latest, windows-latest ] + os: [ubuntu-latest, windows-latest] steps: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 @@ -33,4 +33,13 @@ jobs: override: true components: clippy - run: cargo clippy --tests --all-targets -- -D warnings - + fmt_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + components: rustfmt + - run: cargo fmt --all -- --check diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 69b1f03a..db40ca4c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,9 @@ To compile from source, see the `Compiling from source` tab in the [docs](https: ## Running Tests -Synth has reasonable test coverage - and we are working on improving this every day. We encourage PRs to come with tests. If you're not sure about what a test shoud look like get in touch. +Synth has reasonable test coverage - and we are working on improving this +every day. We encourage PRs to come with tests. If you're not sure about +what a test should look like, feel free to get in touch. To run the test suite - just run `cargo test` at the root of the repository. @@ -21,3 +23,6 @@ We use the [Angular Commit Guidelines](https://github.com/angular/angular/blob/m Furthermore, commits should be squashed before being merged to master. Also, make sure your commits don't trigger any warnings from Clippy by running: `cargo clippy --tests --all-targets`. If you have a good reason to contradict Clippy, insert an #allow[] macro, so that it won't complain. + +Plus, make sure your commits are properly formatted. You can automate this +process by copying over the `pre-commit` file in `tools/hooks/pre-commit` to `.git/hooks/pre-commit` which will make git automatically format your code before committing them. diff --git a/core/src/compile/address.rs b/core/src/compile/address.rs index f04114ba..53094c93 100644 --- a/core/src/compile/address.rs +++ b/core/src/compile/address.rs @@ -165,4 +165,4 @@ impl From for Address { fn from(field: FieldRef) -> Self { field.into_iter().collect() } -} \ No newline at end of file +} diff --git a/core/src/compile/link.rs b/core/src/compile/link.rs index 6e33e1dd..9394238c 100644 --- a/core/src/compile/link.rs +++ b/core/src/compile/link.rs @@ -1,15 +1,15 @@ use synth_gen::prelude::{Generator, GeneratorState}; use std::cell::RefCell; +use std::iter::IntoIterator; use std::ops::Range; use std::rc::Rc; -use std::iter::IntoIterator; use crate::graph::prelude::Rng; pub struct Slice { generation: usize, - start: usize + start: usize, } pub struct Tape { @@ -21,7 +21,7 @@ impl Tape { fn new() -> Self { Self { slices: Vec::new(), - buffer: Vec::new() + buffer: Vec::new(), } } @@ -52,7 +52,7 @@ pub type SharedTape = Rc>>; pub(super) struct SliceRef { index: usize, - tape: SharedTape + tape: SharedTape, } pub(super) type GeneratorSliceRef = SliceRef; @@ -61,7 +61,7 @@ impl Clone for SliceRef { fn clone(&self) -> Self { Self { index: self.index, - tape: self.tape.clone() + tape: self.tape.clone(), } } } @@ -75,7 +75,7 @@ impl SliceRef { TapeView(TapeViewImpl { slice: self.clone(), generation: 0, - range: Range::default() + range: Range::default(), }) } @@ -99,22 +99,22 @@ impl RecorderImpl { let mut tape = (*self.tape).borrow_mut(); let slice = Slice { generation: 0, - start: tape.buffer.len() + start: tape.buffer.len(), }; tape.slices.push(slice); tape.slices.len() - 1 }; SliceRef { index, - tape: self.tape.clone() + tape: self.tape.clone(), } } } impl Generator for RecorderImpl - where - G: Generator, - GeneratorState: Clone, +where + G: Generator, + GeneratorState: Clone, { type Yield = Y; @@ -128,8 +128,8 @@ impl Generator for RecorderImpl } impl RecorderImpl - where - G: Generator, +where + G: Generator, { fn complete(&mut self, rng: &mut RR) { #[allow(clippy::blocks_in_if_conditions)] @@ -158,14 +158,14 @@ impl Recorder { pub(super) fn wrap(inner: G) -> Self { Self(RecorderImpl { inner, - tape: Rc::new(RefCell::new(Tape::new())) + tape: Rc::new(RefCell::new(Tape::new())), }) } } impl Recorder - where - G: Generator, +where + G: Generator, { fn complete(&mut self, rng: &mut RR) { self.0.complete(rng) @@ -175,7 +175,7 @@ impl Recorder pub(super) struct TapeViewImpl { slice: SliceRef, generation: usize, - range: Range + range: Range, } impl TapeViewImpl { @@ -229,17 +229,15 @@ pub(super) struct OrderedImpl { } impl Generator for OrderedImpl - where - G: Generator, +where + G: Generator, { type Yield = Y; type Return = R; fn next(&mut self, rng: &mut RR) -> GeneratorState { if !self.is_complete { - self.scope.iter_mut().for_each(|slice| { - slice.reset() - }); + self.scope.iter_mut().for_each(|slice| slice.reset()); self.children.iter_mut().for_each(|(_, recorder)| { recorder.complete(rng); }); @@ -265,13 +263,13 @@ impl Ordered { pub(super) fn new(scope: S, children: C, src: G) -> Self where S: IntoIterator>, - C: IntoIterator)> + C: IntoIterator)>, { Self(OrderedImpl { is_complete: false, scope: scope.into_iter().collect(), children: children.into_iter().collect(), - src + src, }) } } @@ -286,13 +284,13 @@ pub enum Link { Ordered(Ordered), /// A variant used in compilation as a placeholder prior to setting the node to its final /// value. - Dummy + Dummy, } impl Generator for Link where G: Generator, - GeneratorState: Clone + GeneratorState: Clone, { type Yield = Y; @@ -303,7 +301,7 @@ where Self::Recorder(Recorder(recorder)) => recorder.next(rng).map_complete(Some), Self::View(TapeView(view)) => view.next(rng), Self::Ordered(Ordered(ordered)) => ordered.next(rng).map_complete(Some), - Self::Dummy => panic!("tried to generate values from a dummy") + Self::Dummy => panic!("tried to generate values from a dummy"), } } } @@ -317,8 +315,8 @@ impl Link { match self { Self::Ordered(Ordered(OrderedImpl { children, .. })) => { Some(children.iter().map(|(name, _)| name.as_str())) - }, - _ => None + } + _ => None, } } } @@ -337,4 +335,4 @@ pub trait FromLink: Sized { fn dummy() -> Self { Self::from_link(Link::new_dummy()) } -} \ No newline at end of file +} diff --git a/core/src/compile/mod.rs b/core/src/compile/mod.rs index 1a515f1b..eb58bd9d 100644 --- a/core/src/compile/mod.rs +++ b/core/src/compile/mod.rs @@ -26,14 +26,14 @@ use std::iter::IntoIterator; use anyhow::{Context, Result}; mod state; -use state::{CompilerState, OutputState, Artifact, Source, Symbols}; +use state::{Artifact, CompilerState, OutputState, Source, Symbols}; mod address; use address::Address; pub mod link; pub use link::{FromLink, Link}; -use link::{Recorder, Ordered, GeneratorSliceRef, GeneratorRecorder}; +use link::{GeneratorRecorder, GeneratorSliceRef, Ordered, Recorder}; use crate::graph::Graph; use crate::schema::{Content, Namespace}; @@ -100,9 +100,9 @@ impl<'a> NamespaceCompiler<'a> { let mut pushbacks = BTreeSet::new(); for target in state.refs().iter() { // Direct references go first - let is_built = self.vtable - .is_built(&address, target) - .ok_or_else(|| anyhow!("undefined reference to `{}` from `{}`", target, address))?; + let is_built = self.vtable.is_built(&address, target).ok_or_else(|| { + anyhow!("undefined reference to `{}` from `{}`", target, address) + })?; if !is_built { debug!("direct reference to `{}`", target); targets.insert(target.clone()); @@ -113,10 +113,7 @@ impl<'a> NamespaceCompiler<'a> { if !relative_to.is_root() { let child = relative_to.deeper().unwrap(); root.at(&child); - let is_built = self.state - .project(root.clone())? - .output() - .is_built(); + let is_built = self.state.project(root.clone())?.output().is_built(); if !is_built && !relative_to.is_root() { debug!("pushback dependency to `{}`", root); pushbacks.insert(root); @@ -134,7 +131,8 @@ impl<'a> NamespaceCompiler<'a> { let child_address = address.clone().into_at(&child); if !is_built && !targets.contains(&child_address) - && !pushbacks.contains(&child_address) { + && !pushbacks.contains(&child_address) + { Some(child_address) } else { None @@ -151,9 +149,15 @@ impl<'a> NamespaceCompiler<'a> { if !next.is_empty() { debug!("dependencies not satisfied: {:?}", next); - if matches!(self.state.project_mut(address.clone())?.output_mut().waiting(), OutputState::Waiting) { - // This node was visited once and was waiting for dependencies to be built first, - // then is now being visited a second time so is a dependency of itself. + if matches!( + self.state + .project_mut(address.clone())? + .output_mut() + .waiting(), + OutputState::Waiting + ) { + // This node was visited once and was waiting for dependencies to be built first, + // then is now being visited a second time so is a dependency of itself. return Err(anyhow!("cycle detected at {}", address)); } visits.push(address); @@ -166,7 +170,11 @@ impl<'a> NamespaceCompiler<'a> { let this = parent.shallower().unwrap(); // It is not necessary to order nodes that are not bound to be wrapped in `Ordered` if self.vtable.contains(&parent) { - self.state.project_mut(parent)?.scope_mut().push(this).unwrap(); + self.state + .project_mut(parent)? + .scope_mut() + .push(this) + .unwrap(); } } @@ -177,7 +185,7 @@ impl<'a> NamespaceCompiler<'a> { scope: address.clone(), state, children: &mut children, - vtable + vtable, }; let mut node = content_compiler @@ -186,9 +194,10 @@ impl<'a> NamespaceCompiler<'a> { if let Some(local_table) = vtable.get(&address) { // `node` must be wrapped in `Ordered` - let mut scope = local_table.values().map(|factory| { - factory.get_source().unwrap() - }).collect::>(); + let mut scope = local_table + .values() + .map(|factory| factory.get_source().unwrap()) + .collect::>(); let mut ordered_children = Vec::new(); for child in state.scope().iter_ordered() { let (recorder, slice_ref) = children.remove(child).unwrap(); @@ -204,10 +213,13 @@ impl<'a> NamespaceCompiler<'a> { let artifact = if vtable.targetted(&address) { let recorder = Recorder::wrap(node); - vtable.paths(&address).into_iter().try_for_each(|(root, tail)| { - debug!("setting source root=`{}` tail=`{}`", root, tail); - vtable.set_source(&root, &tail, recorder.new_slice()) - })?; + vtable + .paths(&address) + .into_iter() + .try_for_each(|(root, tail)| { + debug!("setting source root=`{}` tail=`{}`", root, tail); + vtable.set_source(&root, &tail, recorder.new_slice()) + })?; Artifact::from_recorder(recorder) } else { Artifact::just(node) @@ -251,7 +263,8 @@ impl<'c, 'a: 'c> Compiler<'a> for ContentCompiler<'c, 'a> { let slice_ref = recorder.new_slice(); let view = slice_ref.new_view(); child = Artifact::from_view(view); - self.children.insert(field.to_string(), (recorder, slice_ref)); + self.children + .insert(field.to_string(), (recorder, slice_ref)); } Ok(child.pack()) @@ -259,8 +272,13 @@ impl<'c, 'a: 'c> Compiler<'a> for ContentCompiler<'c, 'a> { fn get>(&mut self, field: S) -> Result { let address = field.into(); - let view = self.vtable.issue(&self.scope, &address) - .with_context(|| anyhow!("while trying to access a reference to `{}` at `{}`", address, self.scope))?; + let view = self.vtable.issue(&self.scope, &address).with_context(|| { + anyhow!( + "while trying to access a reference to `{}` at `{}`", + address, + self.scope + ) + })?; Ok(Graph::from_link(Link::View(view))) } } @@ -293,7 +311,10 @@ impl<'t, 'a: 't> Crawler<'t, 'a> { impl<'t, 'a: 't> Compiler<'a> for Crawler<'t, 'a> { fn build(&mut self, field: &str, content: &'a Content) -> Result { if let Err(err) = self.as_at(field, content).compile() { - warn!("could not crawl into field `{}` at `{}`", field, self.position); + warn!( + "could not crawl into field `{}` at `{}`", + field, self.position + ); return Err(err); } Ok(Graph::dummy()) @@ -301,7 +322,8 @@ impl<'t, 'a: 't> Compiler<'a> for Crawler<'t, 'a> { fn get>(&mut self, target: S) -> Result { let target: Address = target.into(); - self.symbols.declare(self.position.clone(), target.clone())?; + self.symbols + .declare(self.position.clone(), target.clone())?; self.state.refs_mut().insert(target); Ok(Graph::dummy()) } @@ -309,8 +331,8 @@ impl<'t, 'a: 't> Compiler<'a> for Crawler<'t, 'a> { #[cfg(test)] pub mod tests { - use crate::tests::complete; use crate::graph::Value; + use crate::tests::complete; use synth_gen::prelude::*; @@ -373,7 +395,15 @@ pub mod tests { let value = complete(generator).unwrap(); let as_object = value.as_object().unwrap(); for i in 0..5 { - assert!(as_object.get(&i.to_string()).unwrap().as_object().unwrap().get("0").unwrap().as_bool().unwrap()) + assert!(as_object + .get(&i.to_string()) + .unwrap() + .as_object() + .unwrap() + .get("0") + .unwrap() + .as_bool() + .unwrap()) } } @@ -459,7 +489,14 @@ pub mod tests { }, "1": "@0.01" }); - assert!(complete(generator).unwrap().as_object().unwrap().get("1").unwrap().as_bool().unwrap()) + assert!(complete(generator) + .unwrap() + .as_object() + .unwrap() + .get("1") + .unwrap() + .as_bool() + .unwrap()) } #[test] @@ -486,9 +523,13 @@ pub mod tests { let number = as_object.get(&i.to_string()).unwrap().as_number().unwrap(); assert!(matches!(number, Number::U64(1))); } - assert!(as_object.get("4").unwrap().as_array().unwrap().iter().all(|v| { - matches!(v.as_number().unwrap(), Number::U64(1)) - })) + assert!(as_object + .get("4") + .unwrap() + .as_array() + .unwrap() + .iter() + .all(|v| { matches!(v.as_number().unwrap(), Number::U64(1)) })) } #[test] @@ -534,15 +575,28 @@ pub mod tests { let as_object = value.as_object().unwrap(); let two = as_object.get("2").unwrap().as_array().unwrap(); - for (i, v) in as_object.get("0").unwrap().as_array().unwrap().iter().enumerate() { + for (i, v) in as_object + .get("0") + .unwrap() + .as_array() + .unwrap() + .iter() + .enumerate() + { let ii = (i + 1) as u64; assert_eq!(*v, Value::Number(Number::U64(ii))); assert_eq!(*two.get(i).unwrap(), Value::Number(Number::U64(ii))); } - assert!(matches!(as_object.get("1").unwrap().as_number().unwrap(), Number::U64(1))); + assert!(matches!( + as_object.get("1").unwrap().as_number().unwrap(), + Number::U64(1) + )); - assert!(matches!(as_object.get("22").unwrap().as_number().unwrap(), Number::U64(1))); + assert!(matches!( + as_object.get("22").unwrap().as_number().unwrap(), + Number::U64(1) + )); let three = as_object.get("3").unwrap().as_array().unwrap(); let mut idx = 0; diff --git a/core/src/compile/state.rs b/core/src/compile/state.rs index fcfed327..a5b849b4 100644 --- a/core/src/compile/state.rs +++ b/core/src/compile/state.rs @@ -5,9 +5,9 @@ use std::iter::FromIterator; use synth_gen::prelude::*; +use super::link::{Recorder, SliceRef, TapeView}; use super::Address; -use super::{Link, FromLink}; -use super::link::{TapeView, Recorder, SliceRef}; +use super::{FromLink, Link}; use crate::schema::{Content, Namespace}; @@ -55,7 +55,8 @@ impl<'a, G: Generator> StructuredState<'a, G> { #[inline] pub(super) fn iter_values(&self) -> impl Iterator> { - self.iter_keys().map(move |key| self.children.get(&key).unwrap()) + self.iter_keys() + .map(move |key| self.children.get(&key).unwrap()) } #[inline] @@ -66,7 +67,11 @@ impl<'a, G: Generator> StructuredState<'a, G> { }) } - pub(super) fn insert(&mut self, name: String, state: CompilerState<'a, G>) -> Option> { + pub(super) fn insert( + &mut self, + name: String, + state: CompilerState<'a, G>, + ) -> Option> { self.children.insert(name, state) } } @@ -91,8 +96,9 @@ impl<'a, G: Generator> IntoIterator for StructuredState<'a, G> { } } - -impl<'a, G: Generator> std::iter::Extend<(String, CompilerState<'a, G>)> for StructuredState<'a, G> { +impl<'a, G: Generator> std::iter::Extend<(String, CompilerState<'a, G>)> + for StructuredState<'a, G> +{ fn extend)>>(&mut self, iter: T) { for (name, state) in iter { self.insert(name, state); @@ -183,7 +189,7 @@ pub(super) enum Artifact { impl Artifact where - G: Generator + FromLink + G: Generator + FromLink, { pub(super) fn pack(self) -> G { match self { @@ -395,9 +401,9 @@ impl Default for ReferenceFactory { } impl ReferenceFactory - where - G: Generator, - GeneratorOutput: Clone, +where + G: Generator, + GeneratorOutput: Clone, { fn declare(&mut self, from: Address) -> bool { self.issued.insert(from) @@ -405,11 +411,17 @@ impl ReferenceFactory fn issue(&mut self, from: &Address) -> Result> { if !self.issued.contains(from) { - Err(anyhow!("cannot issue a reference to `{}` unless it was previously declared", from)) + Err(anyhow!( + "cannot issue a reference to `{}` unless it was previously declared", + from + )) } else if let Some(slice_ref) = self.src.as_ref() { Ok(slice_ref.new_view()) } else { - Err(anyhow!("tried to issue a reference to `{}` before it was built", from)) + Err(anyhow!( + "tried to issue a reference to `{}` before it was built", + from + )) } } @@ -417,7 +429,10 @@ impl ReferenceFactory self.src.is_some() } - fn set_source(&mut self, inner: SliceRef) -> Option> { + fn set_source( + &mut self, + inner: SliceRef, + ) -> Option> { std::mem::replace(&mut self.src, Some(inner)) } @@ -434,8 +449,8 @@ pub(super) struct LocalTable { } impl Default for LocalTable - where - G: Generator, +where + G: Generator, { fn default() -> Self { Self { @@ -445,9 +460,9 @@ impl Default for LocalTable } impl LocalTable - where - G: Generator, - GeneratorOutput: Clone, +where + G: Generator, + GeneratorOutput: Clone, { fn get(&self, to: &Address) -> Option<&ReferenceFactory> { self.locals.get(to) @@ -483,9 +498,9 @@ pub(super) struct Symbols { } impl Symbols - where - G: Generator, - GeneratorOutput: Clone, +where + G: Generator, + GeneratorOutput: Clone, { pub(super) fn new() -> Self { Self { @@ -503,8 +518,7 @@ impl Symbols } pub(super) fn paths(&self, to: &Address) -> Vec<(Address, Address)> { - self - .storage + self.storage .iter() .filter_map(|(root, table)| { let rem = to.as_in(root)?; @@ -554,7 +568,11 @@ impl Symbols Ok(already_declared) } - pub(super) fn issue(&mut self, from: &Address, to: &Address) -> Result> { + pub(super) fn issue( + &mut self, + from: &Address, + to: &Address, + ) -> Result> { let (root, relative_what) = to.relativize(from); let relative_to = from.as_in(&root).unwrap(); self.get_mut(&root) @@ -568,13 +586,15 @@ impl Symbols relative: &Address, source: SliceRef, ) -> Result<()> { - if self.get_mut(root) + if self + .get_mut(root) .ok_or_else(|| anyhow!("no vtable entry for {}", root))? .get_mut(relative) .ok_or_else(|| anyhow!("no local table entry for {}", relative))? .set_source(source) .map(|_| ()) - .is_some() { + .is_some() + { Err(anyhow!("source already set")) } else { Ok(()) diff --git a/core/src/graph/array.rs b/core/src/graph/array.rs index def038ec..e44ed45b 100644 --- a/core/src/graph/array.rs +++ b/core/src/graph/array.rs @@ -28,8 +28,7 @@ impl Generator for RandomArray { } } -type ArrayNodeInner = - AndThenTry RandomArray>, RandomArray>; +type ArrayNodeInner = AndThenTry RandomArray>, RandomArray>; derive_generator! { yield Token, diff --git a/core/src/graph/date_time.rs b/core/src/graph/date_time.rs index 6228fe1e..60f81ecb 100644 --- a/core/src/graph/date_time.rs +++ b/core/src/graph/date_time.rs @@ -10,7 +10,11 @@ derive_generator! { impl From for DateTimeNode { fn from(value: RandomDateTime) -> Self { - Self(value.into_token().map_complete(value_from_ok::)) + Self( + value + .into_token() + .map_complete(value_from_ok::), + ) } } @@ -80,7 +84,12 @@ impl Generator for RandomDateTime { Err(err) => GeneratorState::Complete(Err(err)), } } - GeneratorState::Complete(r) => GeneratorState::Complete(r.map(|value| ChronoValueAndFormat { value, format: Arc::clone(&self.format)})), + GeneratorState::Complete(r) => { + GeneratorState::Complete(r.map(|value| ChronoValueAndFormat { + value, + format: Arc::clone(&self.format), + })) + } } } } diff --git a/core/src/graph/json.rs b/core/src/graph/json.rs index 9fb726c9..7bd91d82 100644 --- a/core/src/graph/json.rs +++ b/core/src/graph/json.rs @@ -1,7 +1,7 @@ +use crate::Value; use serde_json::Map; use std::collections::BTreeMap; use synth_gen::value::Number; -use crate::Value; pub fn synth_val_to_json(val: Value) -> serde_json::Value { match val { @@ -27,8 +27,10 @@ fn synth_num_to_json(n: Number) -> serde_json::Number { Number::U32(u32) => serde_json::Number::from(u32), Number::U64(u64) => serde_json::Number::from(u64), Number::U128(u128) => serde_json::Number::from(u128 as u64), - Number::F32(f32) => serde_json::Number::from_f64(*f32 as f64).unwrap_or_else(|| panic!("Could not convert value '{}' to JSON f64", f32)), - Number::F64(f64) => serde_json::Number::from_f64(*f64).unwrap_or_else(|| panic!("Could not convert value '{}' to JSON f64", f64)), + Number::F32(f32) => serde_json::Number::from_f64(*f32 as f64) + .unwrap_or_else(|| panic!("Could not convert value '{}' to JSON f64", f32)), + Number::F64(f64) => serde_json::Number::from_f64(*f64) + .unwrap_or_else(|| panic!("Could not convert value '{}' to JSON f64", f64)), } } diff --git a/core/src/graph/mod.rs b/core/src/graph/mod.rs index 971be5d8..9e153b9d 100644 --- a/core/src/graph/mod.rs +++ b/core/src/graph/mod.rs @@ -4,14 +4,14 @@ use anyhow::{Context, Result}; use chrono::{DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime, Utc}; use sqlx::mysql::MySqlTypeInfo; -use sqlx::{MySql, Postgres}; use sqlx::postgres::{PgArgumentBuffer, PgTypeInfo}; -use sqlx::{Type, Encode, encode::IsNull}; +use sqlx::{encode::IsNull, Encode, Type}; +use sqlx::{MySql, Postgres}; use synth_gen::prelude::*; use synth_gen::value::{Token, Tokenizer}; -use crate::compile::{NamespaceCompiler, Link}; +use crate::compile::{Link, NamespaceCompiler}; use crate::schema::{ChronoValueAndFormat, Namespace}; @@ -22,15 +22,16 @@ pub mod null; pub use null::NullNode; pub mod string; -pub use string::{ - Format, FormatArgs, RandFaker, RandomString, StringNode, Truncated, UuidGen, -}; +pub use string::{Format, FormatArgs, RandFaker, RandomString, StringNode, Truncated, UuidGen}; pub mod date_time; -pub use date_time::{RandomDateTime, DateTimeNode}; +pub use date_time::{DateTimeNode, RandomDateTime}; pub mod number; -pub use number::{Incrementing, NumberNode, RandomF64, RandomI64, RandomU64, StandardIntRangeStep, StandardFloatRangeStep}; +pub use number::{ + Incrementing, NumberNode, RandomF64, RandomI64, RandomU64, StandardFloatRangeStep, + StandardIntRangeStep, +}; pub mod boolean; pub use boolean::{BoolNode, RandomBool}; @@ -121,13 +122,16 @@ where T: TryFrom, T::Error: std::error::Error, { - value - .and_then(|v| v.try_into()) - .and_then(|n: Number| { - n.try_into().map_err(|err| { - failed_crate!(target: Release, "could not convert from value '{}': {}", n, err) - }) + value.and_then(|v| v.try_into()).and_then(|n: Number| { + n.try_into().map_err(|err| { + failed_crate!( + target: Release, + "could not convert from value '{}': {}", + n, + err + ) }) + }) } pub fn unsigned_from_ok(value: Result) -> Result { @@ -135,15 +139,14 @@ pub fn unsigned_from_ok(value: Result) -> Result { .or_else(|_| number_from_ok::(value).map(|sm| sm as u64)) } -pub fn string_from_ok(value: Result) -> Result -{ - value.and_then(|n| { - match n { - Value::String(s) => Ok(s), - otherwise => Err( - failed_crate!(target: Release, "could not get a string from a value '{}'", otherwise) - ) - } +pub fn string_from_ok(value: Result) -> Result { + value.and_then(|n| match n { + Value::String(s) => Ok(s), + otherwise => Err(failed_crate!( + target: Release, + "could not get a string from a value '{}'", + otherwise + )), }) } @@ -198,7 +201,6 @@ impl Display for Value { } } - /// Claim we are an unknown type since we don't have a reference to `self` to use. impl Type for Value { fn type_info() -> PgTypeInfo { @@ -221,120 +223,135 @@ impl Type for Value { } impl Encode<'_, Postgres> for Value { - fn encode_by_ref( - &self, - buf: &mut PgArgumentBuffer - ) -> IsNull { + fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { match self { Value::Null(_) => IsNull::Yes, Value::Bool(b) => >::encode_by_ref(b, buf), - Value::Number(num) => { - match *num { - Number::I8(i) => >::encode_by_ref(&i, buf), - Number::I16(i) => >::encode_by_ref(&i, buf), - Number::I32(i) => >::encode_by_ref(&i, buf), - Number::I64(i) => >::encode_by_ref(&i, buf), - Number::I128(i) => >::encode_by_ref(&i.into(), buf), - Number::U8(i) => >::encode_by_ref(&(i as i8), buf), - Number::U16(i) => >::encode_by_ref(&(i as i16), buf), - Number::U32(i) => >::encode_by_ref(&i, buf), - Number::U64(i) => >::encode_by_ref(&(i as i64), buf), - Number::U128(i) => >::encode_by_ref(&i.into(), buf), - Number::F32(f) => >::encode_by_ref(&f, buf), - Number::F64(f) => >::encode_by_ref(&f, buf), + Value::Number(num) => match *num { + Number::I8(i) => >::encode_by_ref(&i, buf), + Number::I16(i) => >::encode_by_ref(&i, buf), + Number::I32(i) => >::encode_by_ref(&i, buf), + Number::I64(i) => >::encode_by_ref(&i, buf), + Number::I128(i) => { + >::encode_by_ref(&i.into(), buf) + } + Number::U8(i) => >::encode_by_ref(&(i as i8), buf), + Number::U16(i) => >::encode_by_ref(&(i as i16), buf), + Number::U32(i) => >::encode_by_ref(&i, buf), + Number::U64(i) => >::encode_by_ref(&(i as i64), buf), + Number::U128(i) => { + >::encode_by_ref(&i.into(), buf) } + Number::F32(f) => >::encode_by_ref(&f, buf), + Number::F64(f) => >::encode_by_ref(&f, buf), }, Value::String(s) => >::encode_by_ref(s, buf), - Value::DateTime(ChronoValueAndFormat { value, .. }) => { - match value { - ChronoValue::NaiveDate(nd) => >::encode_by_ref(nd, buf), - ChronoValue::NaiveTime(nt) => >::encode_by_ref(nt, buf), - ChronoValue::NaiveDateTime(ndt) => >::encode_by_ref(ndt, buf), - ChronoValue::DateTime(dt) => as Encode<'_, Postgres>>::encode_by_ref(dt, buf), + Value::DateTime(ChronoValueAndFormat { value, .. }) => match value { + ChronoValue::NaiveDate(nd) => { + >::encode_by_ref(nd, buf) + } + ChronoValue::NaiveTime(nt) => { + >::encode_by_ref(nt, buf) + } + ChronoValue::NaiveDateTime(ndt) => { + >::encode_by_ref(ndt, buf) + } + ChronoValue::DateTime(dt) => { + as Encode<'_, Postgres>>::encode_by_ref(dt, buf) } - } - Value::Object(_) => { - >::encode(json::synth_val_to_json(self.clone()), buf) }, + Value::Object(_) => >::encode( + json::synth_val_to_json(self.clone()), + buf, + ), Value::Array(arr) => arr.encode_by_ref(buf), //TODO special-case for BYTEA } } } impl Encode<'_, MySql> for Value { - fn encode_by_ref( - &self, - buf: &mut Vec - ) -> IsNull { + fn encode_by_ref(&self, buf: &mut Vec) -> IsNull { match self { Value::Null(_) => IsNull::Yes, Value::Bool(b) => >::encode_by_ref(b, buf), - Value::Number(num) => { - match *num { - Number::I8(i) => >::encode_by_ref(&i, buf), - Number::I16(i) => >::encode_by_ref(&i, buf), - Number::I32(i) => >::encode_by_ref(&i, buf), - Number::I64(i) => >::encode_by_ref(&i, buf), - Number::I128(i) => >::encode_by_ref(&i.into(), buf), - Number::U8(i) => >::encode_by_ref(&(i as i8), buf), - Number::U16(i) => >::encode_by_ref(&(i as i16), buf), - Number::U32(i) => >::encode_by_ref(&i, buf), - Number::U64(i) => >::encode_by_ref(&(i as i64), buf), - Number::U128(i) => >::encode_by_ref(&i.into(), buf), - Number::F32(f) => >::encode_by_ref(&f, buf), - Number::F64(f) => >::encode_by_ref(&f, buf), + Value::Number(num) => match *num { + Number::I8(i) => >::encode_by_ref(&i, buf), + Number::I16(i) => >::encode_by_ref(&i, buf), + Number::I32(i) => >::encode_by_ref(&i, buf), + Number::I64(i) => >::encode_by_ref(&i, buf), + Number::I128(i) => { + >::encode_by_ref(&i.into(), buf) + } + Number::U8(i) => >::encode_by_ref(&(i as i8), buf), + Number::U16(i) => >::encode_by_ref(&(i as i16), buf), + Number::U32(i) => >::encode_by_ref(&i, buf), + Number::U64(i) => >::encode_by_ref(&(i as i64), buf), + Number::U128(i) => { + >::encode_by_ref(&i.into(), buf) } + Number::F32(f) => >::encode_by_ref(&f, buf), + Number::F64(f) => >::encode_by_ref(&f, buf), }, Value::String(s) => >::encode_by_ref(s, buf), - Value::DateTime(ChronoValueAndFormat { value, .. }) => { - match value { - ChronoValue::NaiveDate(nd) => >::encode_by_ref(nd, buf), - ChronoValue::NaiveTime(nt) => >::encode_by_ref(nt, buf), - ChronoValue::NaiveDateTime(ndt) => >::encode_by_ref(ndt, buf), - ChronoValue::DateTime(dt) => as Encode<'_, MySql>>::encode_by_ref(&dt.with_timezone(&Utc), buf), + Value::DateTime(ChronoValueAndFormat { value, .. }) => match value { + ChronoValue::NaiveDate(nd) => { + >::encode_by_ref(nd, buf) } - } - Value::Object(_) => { - >::encode(json::synth_val_to_json(self.clone()), buf) + ChronoValue::NaiveTime(nt) => { + >::encode_by_ref(nt, buf) + } + ChronoValue::NaiveDateTime(ndt) => { + >::encode_by_ref(ndt, buf) + } + ChronoValue::DateTime(dt) => as Encode<'_, MySql>>::encode_by_ref( + &dt.with_timezone(&Utc), + buf, + ), }, - Value::Array(_arr) => todo!()// as Encode<'_, MySql>>::encode_by_ref(arr, buf), //TODO special-case for u8 arrays? + Value::Object(_) => >::encode( + json::synth_val_to_json(self.clone()), + buf, + ), + Value::Array(_arr) => todo!(), // as Encode<'_, MySql>>::encode_by_ref(arr, buf), //TODO special-case for u8 arrays? } } fn produces(&self) -> Option { Some(match self { - Value::Null(_) => return >::produces(&serde_json::Value::Null), + Value::Null(_) => { + return >::produces(&serde_json::Value::Null) + } Value::Bool(_) => >::type_info(), Value::Number(num) => match num { Number::I8(_) => >::type_info(), Number::I16(_) => >::type_info(), Number::I32(_) => >::type_info(), Number::I64(_) => >::type_info(), - Number::I128(_) =>>::type_info(), - Number::U8(_) => >::type_info(), + Number::I128(_) => >::type_info(), + Number::U8(_) => >::type_info(), Number::U16(_) => >::type_info(), Number::U32(_) => >::type_info(), Number::U64(_) => >::type_info(), - Number::U128(_) =>>::type_info(), + Number::U128(_) => >::type_info(), Number::F32(_) => >::type_info(), Number::F64(_) => >::type_info(), }, - Value::DateTime(ChronoValueAndFormat { value, .. }) => { - match value { - ChronoValue::NaiveDate(_) => >::type_info(), - ChronoValue::NaiveTime(_) => >::type_info(), - ChronoValue::NaiveDateTime(_) => >::type_info(), - ChronoValue::DateTime(_) => as Type>::type_info(), - } + Value::DateTime(ChronoValueAndFormat { value, .. }) => match value { + ChronoValue::NaiveDate(_) => >::type_info(), + ChronoValue::NaiveTime(_) => >::type_info(), + ChronoValue::NaiveDateTime(_) => >::type_info(), + ChronoValue::DateTime(_) => as Type>::type_info(), }, Value::String(_) => >::type_info(), Value::Object(_) => return None, //TODO: Use JSON here? - Value::Array(elems) => if elems.is_empty() { - return None - } else if let Value::Number(Number::U8(_) | Number::I8(_)) = elems[0] { - as Type>::type_info() - } else { - return None //TODO: other variants that would make sense? + Value::Array(elems) => { + if elems.is_empty() { + return None; + } else if let Value::Number(Number::U8(_) | Number::I8(_)) = elems[0] { + as Type>::type_info() + } else { + return None; //TODO: other variants that would make sense? + } } }) } @@ -373,91 +390,94 @@ impl Value { pub fn as_null(&self) -> Option<()> { match *self { Value::Null(()) => Some(()), - _ => None + _ => None, } } pub fn as_bool(&self) -> Option<&bool> { match *self { Value::Bool(ref bool) => Some(bool), - _ => None + _ => None, } } pub fn as_number(&self) -> Option<&Number> { match *self { Value::Number(ref number) => Some(number), - _ => None + _ => None, } } pub fn as_string(&self) -> Option<&String> { match *self { Value::String(ref string) => Some(string), - _ => None + _ => None, } } pub fn as_datetime(&self) -> Option<&ChronoValue> { match *self { Value::DateTime(ref chrono_value) => Some(&chrono_value.value), - _ => None + _ => None, } } pub fn as_object(&self) -> Option<&BTreeMap> { match *self { Value::Object(ref map) => Some(map), - _ => None + _ => None, } } pub fn as_array(&self) -> Option<&Vec> { match *self { Value::Array(ref vec) => Some(vec), - _ => None + _ => None, } } pub fn as_bool_mut(&mut self) -> Option<&mut bool> { match *self { Value::Bool(ref mut bool) => Some(bool), - _ => None + _ => None, } } pub fn as_number_mut(&mut self) -> Option<&mut Number> { match *self { Value::Number(ref mut number) => Some(number), - _ => None + _ => None, } } pub fn as_string_mut(&mut self) -> Option<&mut String> { match *self { Value::String(ref mut string) => Some(string), - _ => None + _ => None, } } pub fn as_datetime_mut(&mut self) -> Option<&mut ChronoValue> { match *self { - Value::DateTime(ChronoValueAndFormat { value: ref mut chrono_value, ..}) => Some(chrono_value), - _ => None + Value::DateTime(ChronoValueAndFormat { + value: ref mut chrono_value, + .. + }) => Some(chrono_value), + _ => None, } } pub fn as_object_mut(&mut self) -> Option<&mut BTreeMap> { match *self { Value::Object(ref mut map) => Some(map), - _ => None + _ => None, } } pub fn as_array_mut(&mut self) -> Option<&mut Vec> { match *self { Value::Array(ref mut vec) => Some(vec), - _ => None + _ => None, } } } @@ -542,7 +562,7 @@ impl Graph { enum LinkNodeState { YieldFrom, Yield(Token), - Return(Value) + Return(Value), } pub struct LinkNode(Link>, LinkNodeState); @@ -564,8 +584,8 @@ impl Generator for Box { LinkNodeState::Yield(token) => { (*self).1 = LinkNodeState::Return(Value::Null(())); GeneratorState::Yielded(token) - }, - LinkNodeState::Return(value) => GeneratorState::Complete(Ok(value)) + } + LinkNodeState::Return(value) => GeneratorState::Complete(Ok(value)), } } } @@ -616,7 +636,7 @@ impl Graph { pub fn iter_ordered(&self) -> Option> { match self { Self::Link(box LinkNode(link, _)) => Some(link.iter_order()?), - _ => None + _ => None, } } } @@ -774,7 +794,9 @@ pub mod tests { }, } } - }).into_namespace().unwrap(); + }) + .into_namespace() + .unwrap(); let mut rng = rand::rngs::StdRng::seed_from_u64(0); diff --git a/core/src/graph/number.rs b/core/src/graph/number.rs index 14ec9a27..45799bde 100644 --- a/core/src/graph/number.rs +++ b/core/src/graph/number.rs @@ -2,7 +2,7 @@ use super::prelude::*; use rand::distributions::uniform::SampleRange; -use num::{One, Zero, CheckedAdd}; +use num::{CheckedAdd, One, Zero}; use std::ops::{Bound, RangeBounds}; @@ -11,7 +11,7 @@ use std::ops::{Bound, RangeBounds}; #[derive(Clone)] struct AnyRange { low: Bound, - high: Bound + high: Bound, } macro_rules! any_range_int_impl { @@ -103,14 +103,14 @@ impl AnyRange { match bound { Bound::Included(n) => write!(f, "{} (inclusive)", n), Bound::Excluded(n) => write!(f, "{} (exclusive)", n), - Bound::Unbounded => write!(f, "unbounded") + Bound::Unbounded => write!(f, "unbounded"), } } } impl std::fmt::Display for AnyRange where - N: std::fmt::Display + N: std::fmt::Display, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "low=")?; @@ -124,7 +124,7 @@ impl AnyRange { fn from_range_bounds>(r: &R) -> Self { Self { low: r.start_bound().cloned(), - high: r.end_bound().cloned() + high: r.end_bound().cloned(), } } } @@ -132,13 +132,13 @@ impl AnyRange { pub struct StandardIntRangeStep { range: AnyRange, step: R, - low: L + low: L, } impl std::fmt::Display for StandardIntRangeStep where R: std::fmt::Display, - L: std::fmt::Display + L: std::fmt::Display, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.range.fmt(f)?; @@ -225,7 +225,7 @@ standard_int_range_step_impl! { u64, u64, u64 } pub struct StandardFloatRangeStep { range: AnyRange, low: Option, - step: Option + step: Option, } macro_rules! standard_float_range_step_impl { @@ -297,8 +297,8 @@ pub struct Incrementing { } impl Incrementing - where - N: One, +where + N: One, { pub fn new() -> Self { Self { @@ -310,8 +310,8 @@ impl Incrementing } impl Incrementing - where - N: One, +where + N: One, { pub fn new_at(start_at: N) -> Self { Self { @@ -333,8 +333,8 @@ impl Incrementing { } impl Default for Incrementing - where - N: Zero + One, +where + N: Zero + One, { fn default() -> Self { Self::new() @@ -342,8 +342,8 @@ impl Default for Incrementing } impl Generator for Incrementing - where - N: CheckedAdd + Copy, +where + N: CheckedAdd + Copy, { type Yield = N; @@ -481,7 +481,7 @@ pub mod test { let mut incrementing: Incrementing = Incrementing { count: 0, step: 1, - overflowed: false + overflowed: false, }; let mut rng = OsRng::default(); diff --git a/core/src/graph/object.rs b/core/src/graph/object.rs index 4f34bba4..2ab70772 100644 --- a/core/src/graph/object.rs +++ b/core/src/graph/object.rs @@ -68,14 +68,21 @@ impl Generator for ObjectNode { type Return = Result; fn next(&mut self, rng: &mut R) -> GeneratorState { - let hidden_fields: std::collections::HashSet = self.0.inner.inner.inners.iter().filter(|&p| p.hidden) - .map(|p| p.key.clone()).collect(); + let hidden_fields: std::collections::HashSet = self + .0 + .inner + .inner + .inners + .iter() + .filter(|&p| p.hidden) + .map(|p| p.key.clone()) + .collect(); self.0.next(rng).map_complete(|kv| { kv.into_iter() .filter(|p| match p { Some((k, _)) => !hidden_fields.contains(k), - _ => true + _ => true, }) .filter_map(|m_kv| m_kv.map(|(k, vr)| vr.map(|v| (k, v)))) .collect::, Error>>() diff --git a/core/src/graph/prelude.rs b/core/src/graph/prelude.rs index 198a6c2f..0ef118bb 100644 --- a/core/src/graph/prelude.rs +++ b/core/src/graph/prelude.rs @@ -22,5 +22,5 @@ pub use anyhow::Error as AnyhowError; pub use super::{ number_from_ok, value_from_ok, value_from_ok_number, Devaluize, Graph, JustToken, - OnceInfallible, OwnedDevaluize, TokenOnce, Value, Valuize, StringGenerator, SizeGenerator + OnceInfallible, OwnedDevaluize, SizeGenerator, StringGenerator, TokenOnce, Value, Valuize, }; diff --git a/core/src/graph/string/format.rs b/core/src/graph/string/format.rs index 91d0a13a..88322d77 100644 --- a/core/src/graph/string/format.rs +++ b/core/src/graph/string/format.rs @@ -86,7 +86,10 @@ impl dynfmt::FormatArgs for FormatArgs { #[cfg(test)] pub mod tests { use super::*; - use crate::graph::{ChronoValue, DateTimeNode, Graph, NumberNode, RandFaker, RandomDateTime, RandomI64, RandomString, StringNode}; + use crate::graph::{ + ChronoValue, DateTimeNode, Graph, NumberNode, RandFaker, RandomDateTime, RandomI64, + RandomString, StringNode, + }; use chrono::naive::NaiveDate; fn faker_graph(name: &str) -> Graph { diff --git a/core/src/graph/unique.rs b/core/src/graph/unique.rs index 04ec5ef3..89a59262 100644 --- a/core/src/graph/unique.rs +++ b/core/src/graph/unique.rs @@ -1,6 +1,4 @@ -use crate::graph::prelude::{ - Error, Rng, Token, TryFilterMap, TryGeneratorExt, Value, -}; +use crate::graph::prelude::{Error, Rng, Token, TryFilterMap, TryGeneratorExt, Value}; use crate::Graph; use std::collections::HashMap; diff --git a/core/src/lib.rs b/core/src/lib.rs index 72bcde42..ed4d1b2b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -66,7 +66,6 @@ macro_rules! schema { } } - #[macro_export] macro_rules! generator { { $($inner:tt)* } => { @@ -81,7 +80,6 @@ macro_rules! try_generator { } } - #[macro_use] extern crate log; @@ -113,7 +111,7 @@ pub use compile::{Compile, Compiler}; #[cfg(test)] pub mod tests { - use rand::{SeedableRng, rngs::StdRng}; + use rand::{rngs::StdRng, SeedableRng}; use synth_gen::prelude::Generator; pub fn rng() -> StdRng { @@ -127,4 +125,4 @@ pub mod tests { pub fn complete_once(generator: &mut G) -> G::Return { generator.complete(&mut rng()) } -} \ No newline at end of file +} diff --git a/core/src/schema/content/array.rs b/core/src/schema/content/array.rs index 85417308..d43ba0a9 100644 --- a/core/src/schema/content/array.rs +++ b/core/src/schema/content/array.rs @@ -13,7 +13,9 @@ pub struct ArrayContent { impl ArrayContent { pub fn from_content_default_length(content: Content) -> Self { Self { - length: Box::new(Content::Number(NumberContent::U64(U64::Range(RangeStep::new(1, 2, 1))))), + length: Box::new(Content::Number(NumberContent::U64(U64::Range( + RangeStep::new(1, 2, 1), + )))), content: Box::new(content), } } @@ -21,8 +23,7 @@ impl ArrayContent { impl Compile for ArrayContent { fn compile<'a, C: Compiler<'a>>(&'a self, mut compiler: C) -> Result { - let length = compiler.build("length", self.length.as_ref())? - .into_size(); + let length = compiler.build("length", self.length.as_ref())?.into_size(); let content = compiler.build("content", &self.content)?; Ok(Graph::Array(ArrayNode::new_with(length, content))) } diff --git a/core/src/schema/content/categorical.rs b/core/src/schema/content/categorical.rs index b07f17e5..a459382a 100644 --- a/core/src/schema/content/categorical.rs +++ b/core/src/schema/content/categorical.rs @@ -141,6 +141,7 @@ pub mod tests { "foo", serde_json::from_value::>(categorical_json) .unwrap() - .sample(&mut rand::thread_rng())) + .sample(&mut rand::thread_rng()) + ) } } diff --git a/core/src/schema/content/date_time.rs b/core/src/schema/content/date_time.rs index 93cd2c8d..a7ec12b0 100644 --- a/core/src/schema/content/date_time.rs +++ b/core/src/schema/content/date_time.rs @@ -17,7 +17,8 @@ impl ChronoValueAndFormat { ChronoValue::NaiveTime(t) => t.format(&self.format), ChronoValue::NaiveDateTime(dt) => dt.format(&self.format), ChronoValue::DateTime(dt) => dt.format(&self.format), - }.to_string() + } + .to_string() } } @@ -169,12 +170,8 @@ impl<'a> ChronoValueFormatter<'a> { ChronoValueType::NaiveDateTime => Ok(ChronoValue::NaiveDateTime( parsed.to_naive_date()?.and_time(parsed.to_naive_time()?), )), - ChronoValueType::NaiveDate => { - Ok(ChronoValue::NaiveDate(parsed.to_naive_date()?)) - } - ChronoValueType::NaiveTime => { - Ok(ChronoValue::NaiveTime(parsed.to_naive_time()?)) - } + ChronoValueType::NaiveDate => Ok(ChronoValue::NaiveDate(parsed.to_naive_date()?)), + ChronoValueType::NaiveTime => Ok(ChronoValue::NaiveTime(parsed.to_naive_time()?)), } } else { parsed @@ -296,7 +293,6 @@ impl SerdeDateTimeContent { } } - impl Serialize for DateTimeContent { fn serialize(&self, serializer: S) -> Result where @@ -386,7 +382,10 @@ pub mod tests { date_time_bounds_test_ok!(None, None); date_time_bounds_test_ok!(None, Some(ChronoValue::NaiveDate(MAX_DATE))); date_time_bounds_test_ok!(Some(ChronoValue::NaiveDate(MIN_DATE)), None); - date_time_bounds_test_ok!(Some(ChronoValue::NaiveDate(MIN_DATE)), Some(ChronoValue::NaiveDate(MAX_DATE))); + date_time_bounds_test_ok!( + Some(ChronoValue::NaiveDate(MIN_DATE)), + Some(ChronoValue::NaiveDate(MAX_DATE)) + ); date_time_bounds_test_err!(Some(ChronoValue::NaiveDate(MAX_DATE)), None); date_time_bounds_test_err!(None, Some(ChronoValue::NaiveDate(MIN_DATE))); diff --git a/core/src/schema/content/hidden.rs b/core/src/schema/content/hidden.rs index 5474ac78..326de4d2 100644 --- a/core/src/schema/content/hidden.rs +++ b/core/src/schema/content/hidden.rs @@ -5,7 +5,6 @@ use crate::{Compiler, Content, Graph}; use anyhow::Result; use serde::{Deserialize, Serialize}; - #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(deny_unknown_fields)] pub struct HiddenContent { diff --git a/core/src/schema/content/mod.rs b/core/src/schema/content/mod.rs index 93b972b1..7f21901c 100644 --- a/core/src/schema/content/mod.rs +++ b/core/src/schema/content/mod.rs @@ -23,10 +23,14 @@ mod number; pub use number::{number_content, NumberContent, NumberContentKind, NumberKindExt, RangeStep}; mod string; -pub use string::{FakerContent, FakerContentArgument, FormatContent, RegexContent, StringContent, Uuid}; +pub use string::{ + FakerContent, FakerContentArgument, FormatContent, RegexContent, StringContent, Uuid, +}; mod date_time; -pub use date_time::{ChronoValue, ChronoValueAndFormat, ChronoValueFormatter, ChronoValueType, DateTimeContent}; +pub use date_time::{ + ChronoValue, ChronoValueAndFormat, ChronoValueFormatter, ChronoValueType, DateTimeContent, +}; mod array; pub use array::ArrayContent; @@ -50,7 +54,7 @@ pub mod unique; pub use unique::{UniqueAlgorithm, UniqueContent}; pub mod hidden; -pub use hidden::{HiddenContent}; +pub use hidden::HiddenContent; use prelude::*; @@ -279,7 +283,9 @@ impl Content { pub fn into_hidden(self) -> Self { if !self.is_hidden() { - Content::Hidden(HiddenContent{ content: Box::new(self) }) + Content::Hidden(HiddenContent { + content: Box::new(self), + }) } else { self } @@ -312,8 +318,10 @@ impl Content { namespace.put_collection(&key.parse()?, content)?; } Ok(namespace) - }, - _ => Err(anyhow!("cannot convert a non-object content to a namespace")) + } + _ => Err(anyhow!( + "cannot convert a non-object content to a namespace" + )), } } @@ -451,13 +459,25 @@ impl<'r> From<&'r Value> for Content { Value::Number(number_value) => { let number_content = if number_value.is_f64() { let value = number_value.as_f64().unwrap(); - NumberContent::F64(number_content::F64::Range(RangeStep::new(value, value + 1., 1.))) + NumberContent::F64(number_content::F64::Range(RangeStep::new( + value, + value + 1., + 1., + ))) } else if number_value.is_u64() { let value = number_value.as_u64().unwrap(); - NumberContent::U64(number_content::U64::Range(RangeStep::new(value, value + 1, 1))) + NumberContent::U64(number_content::U64::Range(RangeStep::new( + value, + value + 1, + 1, + ))) } else if number_value.is_i64() { let value = number_value.as_i64().unwrap(); - NumberContent::I64(number_content::I64::Range(RangeStep::new(value, value + 1, 1))) + NumberContent::I64(number_content::I64::Range(RangeStep::new( + value, + value + 1, + 1, + ))) } else { unreachable!() }; diff --git a/core/src/schema/content/number.rs b/core/src/schema/content/number.rs index 76d62f45..89cf0fdf 100644 --- a/core/src/schema/content/number.rs +++ b/core/src/schema/content/number.rs @@ -2,12 +2,12 @@ use super::prelude::*; use super::Categorical; +use crate::graph::number::{RandomF32, RandomI32, RandomU32}; use serde::{ de::{Deserialize, Deserializer}, ser::Serializer, Serialize, }; -use crate::graph::number::{RandomU32, RandomF32, RandomI32}; #[derive(Clone, Copy)] pub enum NumberContentKind { @@ -245,7 +245,7 @@ pub struct RangeStep { #[serde(skip_serializing_if = "std::clone::Clone::clone")] pub include_low: bool, #[serde(skip_serializing_if = "std::ops::Not::not")] - pub include_high: bool + pub include_high: bool, } impl Default for RangeStep { @@ -255,7 +255,7 @@ impl Default for RangeStep { high: None, step: None, include_low: true, - include_high: false + include_high: false, } } } @@ -274,27 +274,28 @@ impl RangeStep { match value { Some(n) if inclusive => std::ops::Bound::Included(n), Some(n) => std::ops::Bound::Excluded(n), - None => std::ops::Bound::Unbounded + None => std::ops::Bound::Unbounded, } } - fn cast(self, f: F) -> RangeStep - where - F: Fn(N) -> M + fn cast(self, f: F) -> RangeStep + where + F: Fn(N) -> M, { - self.try_cast::<_, _, std::convert::Infallible>(|value| Ok(f(value))).unwrap() + self.try_cast::<_, _, std::convert::Infallible>(|value| Ok(f(value))) + .unwrap() } fn try_cast(self, f: F) -> Result, E> - where - F: Fn(N) -> Result + where + F: Fn(N) -> Result, { Ok(RangeStep:: { low: self.low.map(&f).transpose()?, high: self.high.map(&f).transpose()?, step: self.step.map(&f).transpose()?, include_low: self.include_low, - include_high: self.include_high + include_high: self.include_high, }) } } @@ -321,28 +322,28 @@ number_content!( Range(RangeStep), Categorical(Categorical), Constant(u32), - Id(crate::schema::Id), + Id(crate::schema::Id), }, u64[is_u64, default_u64_range] as U64 { #[default] Range(RangeStep), Categorical(Categorical), Constant(u64), - Id(crate::schema::Id), + Id(crate::schema::Id), }, i32[is_i32, default_i32_range] as I32 { #[default] Range(RangeStep), Categorical(Categorical), Constant(i32), - Id(crate::schema::Id), + Id(crate::schema::Id), }, i64[is_i64, default_i64_range] as I64 { #[default] Range(RangeStep), Categorical(Categorical), Constant(i64), - Id(crate::schema::Id), + Id(crate::schema::Id), }, f64[is_f64, default_f64_range] as F64 { #[default] @@ -380,7 +381,9 @@ impl Compile for NumberContent { RandomI64::categorical(categorical_content.clone()) } number_content::I64::Constant(val) => RandomI64::constant(*val), - number_content::I64::Id(id) => RandomI64::incrementing(Incrementing::new_at(id.start_at.unwrap_or(1))) + number_content::I64::Id(id) => { + RandomI64::incrementing(Incrementing::new_at(id.start_at.unwrap_or(1))) + } }; random_i64.into() } @@ -411,7 +414,9 @@ impl Compile for NumberContent { RandomI32::categorical(categorical_content.clone()) } number_content::I32::Constant(val) => RandomI32::constant(*val), - number_content::I32::Id(id) => RandomI32::incrementing(Incrementing::new_at(id.start_at.unwrap_or(1))) + number_content::I32::Id(id) => { + RandomI32::incrementing(Incrementing::new_at(id.start_at.unwrap_or(1))) + } }; random_i32.into() } @@ -475,20 +480,18 @@ impl Id { let start_at = self.start_at.unwrap_or(1); return if start_at < 0 { Err(failed!( - target: Release, - "cannot cast id with negative start_at to u64" + target: Release, + "cannot cast id with negative start_at to u64" )) } else { Ok(number_content::U64::Id(Id { - start_at: Some(start_at as u64) - }).into()) + start_at: Some(start_at as u64), + }) + .into()) }; } NumberContentKind::I64 => Ok(number_content::I64::Id(self).into()), - NumberContentKind::F64 => Err(failed!( - target: Release, - "cannot cast id f64" - )) + NumberContentKind::F64 => Err(failed!(target: Release, "cannot cast id f64")), } } } @@ -573,7 +576,7 @@ impl number_content::I64 { Ok(number_content::F64::Constant(cast).into()) } }, - Self::Id(id) => id.upcast(to) + Self::Id(id) => id.upcast(to), } } } diff --git a/core/src/schema/content/object.rs b/core/src/schema/content/object.rs index 6b940920..19da9b53 100644 --- a/core/src/schema/content/object.rs +++ b/core/src/schema/content/object.rs @@ -164,11 +164,9 @@ impl Compile for ObjectContent { .build(name, nullable) .map(|graph| KeyValueOrNothing::sometimes(name, graph, false)) } else { - compiler - .build(name, field) - .map(|graph| { - KeyValueOrNothing::always(name, graph, matches!(field, Content::Hidden(_))) - }) + compiler.build(name, field).map(|graph| { + KeyValueOrNothing::always(name, graph, matches!(field, Content::Hidden(_))) + }) } }) .collect::>()?; diff --git a/core/src/schema/content/string.rs b/core/src/schema/content/string.rs index de5ad29f..68258045 100644 --- a/core/src/schema/content/string.rs +++ b/core/src/schema/content/string.rs @@ -221,11 +221,12 @@ impl Compile for StringContent { RandomString::from(Serialized::new_json(inner)).into() } }, - StringContent::Truncated(TruncatedContent { box length, box content }) => { - let content = compiler.build("content", content)? - .into_string(); - let length = compiler.build("length", length)? - .into_size(); + StringContent::Truncated(TruncatedContent { + box length, + box content, + }) => { + let content = compiler.build("content", content)?.into_string(); + let length = compiler.build("length", length)?.into_size(); RandomString::from(Truncated::new(content, length)).into() } StringContent::Uuid(_uuid) => RandomString::from(UuidGen {}).into(), diff --git a/core/src/schema/inference/mod.rs b/core/src/schema/inference/mod.rs index cd97f3fd..489f4178 100644 --- a/core/src/schema/inference/mod.rs +++ b/core/src/schema/inference/mod.rs @@ -10,13 +10,13 @@ pub mod value; pub use value::ValueMergeStrategy; use super::{ - number_content, ArrayContent, BoolContent, Categorical, ChronoValueFormatter, Content, - DateTimeContent, Id, NumberContent, NumberKindExt, ObjectContent, OneOfContent, RangeStep, - StringContent, ValueKindExt, CategoricalType + number_content, ArrayContent, BoolContent, Categorical, CategoricalType, ChronoValueFormatter, + Content, DateTimeContent, Id, NumberContent, NumberKindExt, ObjectContent, OneOfContent, + RangeStep, StringContent, ValueKindExt, }; -use crate::graph::prelude::content::number_content::{I64, I32}; -use num::Zero; +use crate::graph::prelude::content::number_content::{I32, I64}; use crate::schema::UniqueContent; +use num::Zero; pub trait MergeStrategy: std::fmt::Display { fn try_merge(self, master: &mut M, candidate: &C) -> Result<()>; @@ -208,7 +208,7 @@ impl MergeStrategy for OptionalMergeStrategy { impl MergeStrategy, N> for OptionalMergeStrategy where - N: PartialOrd + Copy + N: PartialOrd + Copy, { fn try_merge(self, master: &mut RangeStep, value: &N) -> Result<()> { let low = master.low.get_or_insert(*value); @@ -221,19 +221,18 @@ where impl MergeStrategy, N> for OptionalMergeStrategy where - N: Copy + CategoricalType + N: Copy + CategoricalType, { - fn try_merge( - self, - master: &mut Categorical, - value: &N - ) -> Result<()> { + fn try_merge(self, master: &mut Categorical, value: &N) -> Result<()> { master.push(*value); Ok(()) } } -impl MergeStrategy, N> for OptionalMergeStrategy where N: PartialOrd + Zero + Copy { +impl MergeStrategy, N> for OptionalMergeStrategy +where + N: PartialOrd + Zero + Copy, +{ fn try_merge(self, master: &mut Id, candidate: &N) -> Result<()> { let lower_bound = master.start_at.unwrap_or_else(N::zero); if candidate < &lower_bound { @@ -277,7 +276,7 @@ impl MergeStrategy for OptionalMergeStrategy { number_content::I64::Range(range) => self.try_merge(range, candidate), number_content::I64::Categorical(cat) => self.try_merge(cat, candidate), number_content::I64::Constant(cst) => self.try_merge(cst, candidate), - I64::Id(id) => self.try_merge(id, candidate) + I64::Id(id) => self.try_merge(id, candidate), } } } @@ -308,7 +307,7 @@ impl MergeStrategy for OptionalMergeStrategy { number_content::I32::Range(range) => self.try_merge(range, candidate), number_content::I32::Categorical(cat) => self.try_merge(cat, candidate), number_content::I32::Constant(cst) => self.try_merge(cst, candidate), - I32::Id(id) => self.try_merge(id, candidate) + I32::Id(id) => self.try_merge(id, candidate), } } } @@ -531,7 +530,8 @@ pub mod tests { "high": 10, "step": 1 } - })).unwrap(); + })) + .unwrap(); let error_margin = f64::EPSILON; OptionalMergeStrategy @@ -539,7 +539,9 @@ pub mod tests { .unwrap(); match master { - NumberContent::U64(number_content::U64::Range(RangeStep { low, high, step, .. })) => { + NumberContent::U64(number_content::U64::Range(RangeStep { + low, high, step, .. + })) => { assert_eq!(low, Some(0)); assert_eq!(high, Some(15)); assert_eq!(step, Some(1)); @@ -555,7 +557,9 @@ pub mod tests { .unwrap(); match master { - NumberContent::I64(number_content::I64::Range(RangeStep { low, high, step, .. })) => { + NumberContent::I64(number_content::I64::Range(RangeStep { + low, high, step, .. + })) => { assert_eq!(low, Some(-10)); assert_eq!(high, Some(20)); assert_eq!(step, Some(1)); @@ -571,7 +575,9 @@ pub mod tests { .unwrap(); match master { - NumberContent::F64(number_content::F64::Range(RangeStep { low, high, step , .. })) => { + NumberContent::F64(number_content::F64::Range(RangeStep { + low, high, step, .. + })) => { assert!((low.unwrap() - -13.6).abs() < error_margin); assert!((high.unwrap() - 20.6).abs() < error_margin); assert!((step.unwrap() - 1.).abs() < error_margin); diff --git a/core/src/schema/namespace.rs b/core/src/schema/namespace.rs index d28ac5ae..b75f5d28 100644 --- a/core/src/schema/namespace.rs +++ b/core/src/schema/namespace.rs @@ -176,4 +176,4 @@ impl Compile for Namespace { .collect::>()?; Ok(Graph::Object(object_node)) } -} \ No newline at end of file +} diff --git a/gen/src/error.rs b/gen/src/error.rs index f4394ed0..b57e744c 100644 --- a/gen/src/error.rs +++ b/gen/src/error.rs @@ -1,4 +1,4 @@ -use std::fmt::{Display, Debug}; +use std::fmt::{Debug, Display}; use crate::value::{IntoToken, Special, Token}; diff --git a/gen/src/generator/try.rs b/gen/src/generator/try.rs index 4650d512..6d6f475e 100644 --- a/gen/src/generator/try.rs +++ b/gen/src/generator/try.rs @@ -64,7 +64,7 @@ pub trait TryGenerator { loop { match self.try_next(rng) { GeneratorState::Yielded(_) => continue, - GeneratorState::Complete(r) => return r + GeneratorState::Complete(r) => return r, } } } @@ -168,7 +168,7 @@ where fn try_yield(self) -> TryYield { TryYield { inner: self, - yielded: None + yielded: None, } } @@ -267,30 +267,28 @@ where pub struct TryYield { inner: G, - yielded: Option + yielded: Option, } impl Generator for TryYield where G: TryGenerator, - G::Ok: Clone + G::Ok: Clone, { type Yield = G::Ok; type Return = G::Return; fn next(&mut self, rng: &mut R) -> GeneratorState { if let Some(yielded) = std::mem::replace(&mut self.yielded, None) { - return GeneratorState::Complete(Self::Return::from_ok(yielded)) + return GeneratorState::Complete(Self::Return::from_ok(yielded)); } match self.inner.try_complete(rng).into_result() { Ok(ret) => { self.yielded = Some(ret.clone()); GeneratorState::Yielded(ret) - }, - Err(err) => { - GeneratorState::Complete(Self::Return::from_err(err)) } + Err(err) => GeneratorState::Complete(Self::Return::from_err(err)), } } } diff --git a/gen/src/prelude.rs b/gen/src/prelude.rs index 2a6af8a9..e20bb3b3 100644 --- a/gen/src/prelude.rs +++ b/gen/src/prelude.rs @@ -13,8 +13,8 @@ pub use crate::value::{ TokenGeneratorExt, Tokenizer, }; pub use crate::{ - FallibleGenerator, FallibleGeneratorExt, Generator, GeneratorExt, GeneratorResult, - TryGenerator, TryGeneratorExt, GeneratorOutput + FallibleGenerator, FallibleGeneratorExt, Generator, GeneratorExt, GeneratorOutput, + GeneratorResult, TryGenerator, TryGeneratorExt, }; pub use rand::Rng; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..c51666e8 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +edition = "2018" \ No newline at end of file diff --git a/synth/benches/bench.rs b/synth/benches/bench.rs index 8cf56535..cfb7b0de 100644 --- a/synth/benches/bench.rs +++ b/synth/benches/bench.rs @@ -25,7 +25,7 @@ fn bench_generate_n_to_stdout(size: usize) { to: None, seed: Some(0), random: false, - schema: None + schema: None, }; Cli::new().unwrap().run(args).await.unwrap() }); diff --git a/synth/src/cli/config.rs b/synth/src/cli/config.rs index 8b6e846d..bb7301c7 100644 --- a/synth/src/cli/config.rs +++ b/synth/src/cli/config.rs @@ -1,15 +1,14 @@ use anyhow::Result; -use std::sync::{Mutex}; use lazy_static::lazy_static; +use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::path::PathBuf; -use serde::{Serialize, Deserialize}; +use std::sync::Mutex; lazy_static! { static ref CONFIG: Mutex = Mutex::new(Config::new()); } - macro_rules! config { { $($val_name:ident: $ty:ty => $getter:ident, $setter:ident)* @@ -84,4 +83,4 @@ impl Config { .unwrap(); serde_json::to_writer_pretty(&mut config_file_path, &self).unwrap(); } -} \ No newline at end of file +} diff --git a/synth/src/cli/db_utils.rs b/synth/src/cli/db_utils.rs index 3646d3ad..e8095f78 100644 --- a/synth/src/cli/db_utils.rs +++ b/synth/src/cli/db_utils.rs @@ -1,4 +1,4 @@ pub struct DataSourceParams { pub uri: Option, //perhaps uri is not a good name here as this could be a file path - pub schema: Option -} \ No newline at end of file + pub schema: Option, +} diff --git a/synth/src/cli/export.rs b/synth/src/cli/export.rs index 51f23288..1974ce0b 100644 --- a/synth/src/cli/export.rs +++ b/synth/src/cli/export.rs @@ -4,13 +4,13 @@ use anyhow::{Context, Result}; use std::convert::TryFrom; +use crate::cli::db_utils::DataSourceParams; use crate::cli::mongo::MongoExportStrategy; use crate::cli::mysql::MySqlExportStrategy; use crate::datasource::DataSource; use crate::sampler::{Sampler, SamplerOutput}; use async_std::task; use synth_core::{Name, Namespace, Value}; -use crate::cli::db_utils::DataSourceParams; pub trait ExportStrategy { fn export(&self, params: ExportParams) -> Result<()>; @@ -34,19 +34,17 @@ impl TryFrom for Box { match params.uri { None => Ok(Box::new(StdoutExportStrategy {})), Some(uri) => { - let export_strategy: Box = if uri.starts_with("postgres://") || uri.starts_with("postgresql://") { + let export_strategy: Box = if uri.starts_with("postgres://") + || uri.starts_with("postgresql://") + { Box::new(PostgresExportStrategy { uri, schema: params.schema, }) } else if uri.starts_with("mongodb://") { - Box::new(MongoExportStrategy { - uri - }) + Box::new(MongoExportStrategy { uri }) } else if uri.starts_with("mysql://") || uri.starts_with("mariadb://") { - Box::new(MySqlExportStrategy { - uri - }) + Box::new(MySqlExportStrategy { uri }) } else { return Err(anyhow!( "Data sink not recognized. Was expecting one of 'mongodb' or 'postgres' or 'mysql' or 'mariadb'" @@ -67,13 +65,15 @@ pub(crate) fn create_and_insert_values( sampler.sample_seeded(params.collection_name.clone(), params.target, params.seed)?; match values { - SamplerOutput::Collection(collection) => { - insert_data(datasource, params.collection_name.unwrap().to_string(), &collection) - } + SamplerOutput::Collection(collection) => insert_data( + datasource, + params.collection_name.unwrap().to_string(), + &collection, + ), SamplerOutput::Namespace(namespace) => { for (name, collection) in namespace { insert_data(datasource, name, &collection)?; - }; + } Ok(()) } } diff --git a/synth/src/cli/import.rs b/synth/src/cli/import.rs index 99db2c56..3797bfd6 100644 --- a/synth/src/cli/import.rs +++ b/synth/src/cli/import.rs @@ -5,9 +5,9 @@ use std::str::FromStr; use anyhow::{Context, Result}; use serde_json::Value; -use synth_core::{Content, Name}; use synth_core::graph::prelude::{MergeStrategy, OptionalMergeStrategy}; use synth_core::schema::Namespace; +use synth_core::{Content, Name}; use crate::cli::db_utils::DataSourceParams; use crate::cli::mongo::MongoImportStrategy; @@ -32,28 +32,23 @@ impl TryFrom for Box { match params.uri { None => Ok(Box::new(StdinImportStrategy {})), Some(uri) => { - let import_strategy: Box = if uri.starts_with("postgres://") || uri.starts_with("postgresql://") { - Box::new(PostgresImportStrategy { - uri, - schema: params.schema - }) - } else if uri.starts_with("mongodb://") { - Box::new(MongoImportStrategy { - uri, - }) - } else if uri.starts_with("mysql://") || uri.starts_with("mariadb://") { - Box::new(MySqlImportStrategy { - uri, - }) - } else if let Ok(path) = PathBuf::from_str(&uri) { - Box::new(FileImportStrategy { - from_file: path, - }) - } else { - return Err(anyhow!( + let import_strategy: Box = + if uri.starts_with("postgres://") || uri.starts_with("postgresql://") { + Box::new(PostgresImportStrategy { + uri, + schema: params.schema, + }) + } else if uri.starts_with("mongodb://") { + Box::new(MongoImportStrategy { uri }) + } else if uri.starts_with("mysql://") || uri.starts_with("mariadb://") { + Box::new(MySqlImportStrategy { uri }) + } else if let Ok(path) = PathBuf::from_str(&uri) { + Box::new(FileImportStrategy { from_file: path }) + } else { + return Err(anyhow!( "Data source not recognized. Was expecting one of 'mongodb' or 'postgres'" - )) - }; + )); + }; Ok(import_strategy) } } diff --git a/synth/src/cli/import_utils.rs b/synth/src/cli/import_utils.rs index bc8bb662..0e2bfe2f 100644 --- a/synth/src/cli/import_utils.rs +++ b/synth/src/cli/import_utils.rs @@ -7,7 +7,10 @@ use serde_json::Value; use std::convert::TryFrom; use std::str::FromStr; use synth_core::schema::content::number_content::U64; -use synth_core::schema::{ArrayContent, FieldRef, NumberContent, ObjectContent, OptionalMergeStrategy, RangeStep, SameAsContent, UniqueContent}; +use synth_core::schema::{ + ArrayContent, FieldRef, NumberContent, ObjectContent, OptionalMergeStrategy, RangeStep, + SameAsContent, UniqueContent, +}; use synth_core::{Content, Name, Namespace}; use super::json::synth_val_to_json; @@ -23,7 +26,6 @@ struct FieldContentWrapper(Content); pub(crate) fn build_namespace_import( datasource: &T, ) -> Result { - let table_names = task::block_on(datasource.get_table_names()) .with_context(|| "Failed to get table names".to_string())?; @@ -89,13 +91,13 @@ fn populate_namespace_primary_keys( // if the primary key is a number, use an id generator. let pk_node = match node { Content::Number(n) => n.clone().try_transmute_to_id().ok().map(Content::Number), - _ => None + _ => None, }; *node = pk_node.unwrap_or_else(|| { Content::Unique(UniqueContent { algorithm: Default::default(), - content: Box::new(node.clone()) + content: Box::new(node.clone()), }) }); } @@ -158,7 +160,9 @@ impl TryFrom<(&T, Vec)> for Co Ok(Collection { collection: Content::Array(ArrayContent { - length: Box::new(Content::Number(NumberContent::U64(U64::Range(RangeStep::new(1, 2, 1))))), + length: Box::new(Content::Number(NumberContent::U64(U64::Range( + RangeStep::new(1, 2, 1), + )))), content: Box::new(Content::Object(collection)), }), }) diff --git a/synth/src/cli/mod.rs b/synth/src/cli/mod.rs index 5ca7952e..d601f9bb 100644 --- a/synth/src/cli/mod.rs +++ b/synth/src/cli/mod.rs @@ -7,36 +7,34 @@ mod postgres; mod stdf; mod store; +use crate::cli::db_utils::DataSourceParams; use crate::cli::export::{ExportParams, ExportStrategy}; use crate::cli::import::ImportStrategy; use crate::cli::store::Store; -use crate::cli::db_utils::DataSourceParams; use crate::version::print_version_message; -use serde::Serialize; use anyhow::{Context, Result}; -use std::path::PathBuf; -use structopt::StructOpt; -use structopt::clap::AppSettings; use rand::RngCore; -use synth_core::{Name, graph::json}; -use std::process::exit; +use serde::Serialize; use std::convert::TryInto; +use std::path::PathBuf; +use std::process::exit; +use structopt::clap::AppSettings; +use structopt::StructOpt; +use synth_core::{graph::json, Name}; -#[cfg(feature = "telemetry")] -pub mod telemetry; pub(crate) mod config; mod db_utils; +#[cfg(feature = "telemetry")] +pub mod telemetry; pub struct Cli { - store: Store + store: Store, } impl Cli { pub fn new() -> Result { - env_logger::Builder::from_env( - env_logger::Env::default().default_filter_or("warn") - ).init(); + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("warn")).init(); #[cfg(debug_assertions)] { @@ -45,7 +43,7 @@ impl Cli { } Ok(Self { - store: Store::init()? + store: Store::init()?, }) } @@ -63,9 +61,7 @@ impl Cli { pub async fn run(self, args: Args) -> Result<()> { match args { - Args::Init { .. } => { - Ok(()) - }, + Args::Init { .. } => Ok(()), Args::Generate { ref namespace, ref collection, @@ -73,21 +69,26 @@ impl Cli { ref to, seed, random, - schema + schema, } => self.generate( namespace.clone(), collection.clone(), size, to.clone(), Self::derive_seed(random, seed)?, - schema + schema, ), Args::Import { ref namespace, ref collection, ref from, - ref schema - } => self.import(namespace.clone(), collection.clone(), from.clone(), schema.clone()), + ref schema, + } => self.import( + namespace.clone(), + collection.clone(), + from.clone(), + schema.clone(), + ), #[cfg(feature = "telemetry")] Args::Telemetry(cmd) => self.telemetry(cmd), Args::Version => { @@ -119,23 +120,21 @@ impl Cli { path: PathBuf, collection: Option, from: Option, - schema: Option + schema: Option, ) -> Result<()> { // TODO: If ns exists and no collection: break // If collection and ns exists and collection exists: break - let import_strategy: Box = DataSourceParams { - uri: from, - schema - }.try_into()?; + let import_strategy: Box = + DataSourceParams { uri: from, schema }.try_into()?; if let Some(collection) = collection { if self.store.collection_exists(&path, &collection) { return Err(anyhow!("The collection `{}` already exists. Will not import into an existing collection.",Store::relative_collection_path(&path, &collection).display())); } else { - let content = import_strategy - .import_collection(&collection)?; - self.store.save_collection_path(&path, collection, content)?; + let content = import_strategy.import_collection(&collection)?; + self.store + .save_collection_path(&path, collection, content)?; Ok(()) } } else if self.store.ns_exists(&path) { @@ -157,18 +156,15 @@ impl Cli { target: usize, to: Option, seed: u64, - schema: Option + schema: Option, ) -> Result<()> { - let namespace = self .store .get_ns(ns_path.clone()) .context("Unable to open the namespace")?; - let export_strategy: Box = DataSourceParams { - uri: to, - schema - }.try_into()?; + let export_strategy: Box = + DataSourceParams { uri: to, schema }.try_into()?; let params = ExportParams { namespace, @@ -196,7 +192,7 @@ pub enum Args { #[structopt(about = "(DEPRECATED). For backward compatibility and is a no-op.")] Init { #[serde(skip)] - init_path: Option + init_path: Option, }, #[structopt(about = "Generate data from a namespace", alias = "gen")] Generate { @@ -228,8 +224,8 @@ pub enum Args { )] random: bool, #[structopt( - long, - help = "(Postgres only) Specify the schema into which to generate. Defaults to 'public'." + long, + help = "(Postgres only) Specify the schema into which to generate. Defaults to 'public'." )] #[serde(skip)] schema: Option, @@ -255,8 +251,8 @@ pub enum Args { #[serde(skip)] from: Option, #[structopt( - long, - help = "(Postgres only) Specify the schema from which to import. Defaults to 'public'." + long, + help = "(Postgres only) Specify the schema from which to import. Defaults to 'public'." )] #[serde(skip)] schema: Option, @@ -265,7 +261,7 @@ pub enum Args { #[structopt(about = "Toggle anonymous usage data collection")] Telemetry(TelemetryCommand), #[structopt(about = "Version information")] - Version + Version, } #[cfg(feature = "telemetry")] diff --git a/synth/src/cli/mongo.rs b/synth/src/cli/mongo.rs index 162fd676..795f3f4a 100644 --- a/synth/src/cli/mongo.rs +++ b/synth/src/cli/mongo.rs @@ -12,7 +12,7 @@ use std::convert::TryFrom; use std::str::FromStr; use synth_core::graph::prelude::content::number_content::U64; use synth_core::graph::prelude::number_content::I64; -use synth_core::graph::prelude::{NumberContent, ObjectContent, RangeStep, Number, ChronoValue}; +use synth_core::graph::prelude::{ChronoValue, Number, NumberContent, ObjectContent, RangeStep}; use synth_core::schema::number_content::F64; use synth_core::schema::{ ArrayContent, BoolContent, Categorical, ChronoValueType, DateTimeContent, RegexContent, @@ -117,7 +117,11 @@ fn doc_to_content(doc: &Document) -> Content { fn bson_to_content(bson: &Bson) -> Content { match bson { - Bson::Double(d) => Content::Number(NumberContent::F64(F64::Range(RangeStep::new(*d, *d + 1., 0.1)))), + Bson::Double(d) => Content::Number(NumberContent::F64(F64::Range(RangeStep::new( + *d, + *d + 1., + 0.1, + )))), Bson::String(_) => Content::String(StringContent::default()), Bson::Array(array) => { let length = Content::Number(NumberContent::U64(U64::Constant(array.len() as u64))); @@ -140,8 +144,16 @@ fn bson_to_content(bson: &Bson) -> Content { Bson::JavaScriptCodeWithScope(_) => { Content::String(StringContent::Categorical(Categorical::default())) } - Bson::Int32(i) => Content::Number(NumberContent::I64(I64::Range(RangeStep::new(*i as i64, *i as i64 + 1, 1)))), - Bson::Int64(i) => Content::Number(NumberContent::I64(I64::Range(RangeStep::new(*i, *i + 1, 1)))), + Bson::Int32(i) => Content::Number(NumberContent::I64(I64::Range(RangeStep::new( + *i as i64, + *i as i64 + 1, + 1, + )))), + Bson::Int64(i) => Content::Number(NumberContent::I64(I64::Range(RangeStep::new( + *i, + *i + 1, + 1, + )))), Bson::DateTime(_) => Content::DateTime(DateTimeContent { format: "".to_string(), type_: ChronoValueType::DateTime, @@ -162,9 +174,11 @@ impl ExportStrategy for MongoExportStrategy { sampler.sample_seeded(params.collection_name.clone(), params.target, params.seed)?; match output { - SamplerOutput::Collection(values) => { - self.insert_data(params.collection_name.unwrap().to_string(), &values, &mut client) - } + SamplerOutput::Collection(values) => self.insert_data( + params.collection_name.unwrap().to_string(), + &values, + &mut client, + ), SamplerOutput::Namespace(namespace) => { for (name, values) in namespace { self.insert_data(name, &values, &mut client)?; @@ -217,7 +231,7 @@ fn value_to_bson(value: Value) -> Bson { Value::String(s) => Bson::String(s), Value::DateTime(dt) => date_time_to_bson(dt.value), //TODO: format instead? Value::Object(obj) => object_to_bson(obj), - Value::Array(arr) => array_to_bson(arr) + Value::Array(arr) => array_to_bson(arr), } } @@ -226,16 +240,20 @@ fn array_to_bson(array: Vec) -> Bson { } fn object_to_bson(obj: BTreeMap) -> Bson { - let obj = obj.into_iter().map(|(name, value)| (name, value_to_bson(value))).collect(); + let obj = obj + .into_iter() + .map(|(name, value)| (name, value_to_bson(value))) + .collect(); Bson::Document(obj) } - fn date_time_to_bson(datetime: ChronoValue) -> Bson { Bson::DateTime(mongodb::bson::DateTime::from(match datetime { // those are not optimal as BSON doesn't have a way to specify dates or times, just both at once ChronoValue::NaiveDate(nd) => DateTime::::from_utc(nd.and_hms(0, 0, 0), Utc), - ChronoValue::NaiveTime(nt) => DateTime::::from_utc(chrono::naive::MIN_DATE.and_time(nt), Utc), + ChronoValue::NaiveTime(nt) => { + DateTime::::from_utc(chrono::naive::MIN_DATE.and_time(nt), Utc) + } ChronoValue::NaiveDateTime(ndt) => DateTime::::from_utc(ndt, Utc), ChronoValue::DateTime(dt) => dt.into(), })) @@ -254,7 +272,7 @@ fn number_to_bson(number: Number) -> Bson { Number::U64(u64) => Bson::Int64(u64 as i64), Number::U128(u128) => Bson::Int64(u128 as i64), Number::F32(f32) => Bson::Double(*f32 as f64), - Number::F64(f64) => Bson::Double(*f64) + Number::F64(f64) => Bson::Double(*f64), } } diff --git a/synth/src/cli/postgres.rs b/synth/src/cli/postgres.rs index 4b34a191..abf11e93 100644 --- a/synth/src/cli/postgres.rs +++ b/synth/src/cli/postgres.rs @@ -1,7 +1,7 @@ use crate::cli::export::{create_and_insert_values, ExportParams, ExportStrategy}; use crate::cli::import::ImportStrategy; use crate::cli::import_utils::build_namespace_import; -use crate::datasource::postgres_datasource::{PostgresDataSource, PostgresConnectParams}; +use crate::datasource::postgres_datasource::{PostgresConnectParams, PostgresDataSource}; use crate::datasource::DataSource; use anyhow::Result; use serde_json::Value; @@ -11,14 +11,14 @@ use synth_core::{Content, Name}; #[derive(Clone, Debug)] pub struct PostgresExportStrategy { pub uri: String, - pub schema: Option + pub schema: Option, } impl ExportStrategy for PostgresExportStrategy { fn export(&self, params: ExportParams) -> Result<()> { let connect_params = PostgresConnectParams { uri: self.uri.clone(), - schema: self.schema.clone() + schema: self.schema.clone(), }; let datasource = PostgresDataSource::new(&connect_params)?; @@ -30,14 +30,14 @@ impl ExportStrategy for PostgresExportStrategy { #[derive(Clone, Debug)] pub struct PostgresImportStrategy { pub uri: String, - pub schema: Option + pub schema: Option, } impl ImportStrategy for PostgresImportStrategy { fn import(&self) -> Result { let connect_params = PostgresConnectParams { uri: self.uri.clone(), - schema: self.schema.clone() + schema: self.schema.clone(), }; let datasource = PostgresDataSource::new(&connect_params)?; diff --git a/synth/src/cli/telemetry.rs b/synth/src/cli/telemetry.rs index 58c4e020..1a9f6f3b 100644 --- a/synth/src/cli/telemetry.rs +++ b/synth/src/cli/telemetry.rs @@ -3,16 +3,16 @@ use backtrace::Backtrace; use colored::Colorize; use lazy_static::lazy_static; -use std::io::{self, BufRead, Read, Write}; -use std::panic; use std::collections::HashMap; -use std::future::Future; use std::error::Error; +use std::future::Future; +use std::io::{self, BufRead, Read, Write}; +use std::panic; use uuid::Uuid; +use crate::cli::config; use crate::utils::META_OS; use crate::version::version; -use crate::cli::config; use super::{Args, TelemetryCommand}; @@ -43,7 +43,9 @@ fn send_panic_report(synth_command: &str, telemetry_client: &TelemetryClient) { // Newline character is also stored let mut answer = [0; 2]; - stdin.read_exact(&mut answer).context("Couldn't read answer.")?; + stdin + .read_exact(&mut answer) + .context("Couldn't read answer.")?; if answer[0] == b'y' { eprint!("Name: "); @@ -61,7 +63,7 @@ fn send_panic_report(synth_command: &str, telemetry_client: &TelemetryClient) { email = Some(e.trim().to_owned()); } } - + let backtrace = Backtrace::new(); let panic_report = PanicReport::new(username, email, synth_command.to_owned(), backtrace); @@ -101,7 +103,7 @@ pub async fn with_telemetry(args: Args, func: F) -> Result where F: FnOnce(Args) -> Fut, Fut: Future>, - E: AsRef + E: AsRef, { if !is_enabled() { return func(args).await; @@ -123,7 +125,7 @@ where Args::Telemetry(TelemetryCommand::Enable) => "telemetry::enable", Args::Telemetry(TelemetryCommand::Disable) => "telemetry::disable", Args::Telemetry(TelemetryCommand::Status) => "telemetry::status", - Args::Version => "version" + Args::Version => "version", }; func(args) @@ -136,7 +138,7 @@ struct PanicReport { username: Option, email: Option, synth_command: String, - backtrace: Backtrace + backtrace: Backtrace, } impl PanicReport { @@ -144,9 +146,14 @@ impl PanicReport { username: Option, email: Option, synth_command: String, - backtrace: Backtrace + backtrace: Backtrace, ) -> Self { - Self { username, email, synth_command, backtrace } + Self { + username, + email, + synth_command, + backtrace, + } } } @@ -197,27 +204,25 @@ impl TelemetryClient { prop_map.insert("command".to_string(), command_name.to_string()); prop_map.insert("success".to_string(), CommandResult::Success.to_string()); - self.send(EVENT_NAME.to_string(), prop_map) - .or_else(|err| { - info!("failed to push ok of command: {}", err); - Ok(()) - })?; + self.send(EVENT_NAME.to_string(), prop_map).or_else(|err| { + info!("failed to push ok of command: {}", err); + Ok(()) + })?; Ok(output) } pub fn failed(&self, command_name: &str, error: E) -> Result where - E: AsRef + E: AsRef, { let mut prop_map = self.default_telemetry_properties(); prop_map.insert("command".to_string(), command_name.to_string()); prop_map.insert("success".to_string(), CommandResult::Failed.to_string()); - self.send(EVENT_NAME.to_string(), prop_map) - .or_else(|err| { - info!("failed to push err of command: {}", err); - Ok(()) - })?; + self.send(EVENT_NAME.to_string(), prop_map).or_else(|err| { + info!("failed to push err of command: {}", err); + Ok(()) + })?; Err(error) } @@ -225,10 +230,16 @@ impl TelemetryClient { panic_report.backtrace.resolve(); let mut prop_map = self.default_telemetry_properties(); - prop_map.insert("username".to_string(), panic_report.username.unwrap_or_default()); + prop_map.insert( + "username".to_string(), + panic_report.username.unwrap_or_default(), + ); prop_map.insert("email".to_string(), panic_report.email.unwrap_or_default()); prop_map.insert("synth_command".to_string(), panic_report.synth_command); - prop_map.insert("backtrace".to_string(), format!("{:?}", panic_report.backtrace)); + prop_map.insert( + "backtrace".to_string(), + format!("{:?}", panic_report.backtrace), + ); self.send(String::from("synth-panic-report"), prop_map) } diff --git a/synth/src/datasource/mysql_datasource.rs b/synth/src/datasource/mysql_datasource.rs index 9f34e755..ccb94f99 100644 --- a/synth/src/datasource/mysql_datasource.rs +++ b/synth/src/datasource/mysql_datasource.rs @@ -9,6 +9,7 @@ use rust_decimal::prelude::ToPrimitive; use rust_decimal::Decimal; use sqlx::mysql::{MySqlColumn, MySqlPoolOptions, MySqlQueryResult, MySqlRow}; use sqlx::{Column, MySql, Pool, Row, TypeInfo}; +use std::collections::BTreeMap; use std::convert::TryFrom; use std::prelude::rust_2015::Result::Ok; use synth_core::schema::number_content::{F64, I64, U64}; @@ -16,7 +17,6 @@ use synth_core::schema::{ ChronoValueType, DateTimeContent, NumberContent, RangeStep, RegexContent, StringContent, }; use synth_core::{Content, Value}; -use std::collections::BTreeMap; use synth_gen::prelude::*; /// TODO @@ -25,7 +25,7 @@ use synth_gen::prelude::*; /// Ideally, the user can define a way to force certain fields as bool rather than i8. pub struct MySqlDataSource { - pool: Pool + pool: Pool, } #[async_trait] @@ -39,14 +39,13 @@ impl DataSource for MySqlDataSource { .connect(connect_params.as_str()) .await?; - Ok::(MySqlDataSource { - pool - }) + Ok::(MySqlDataSource { pool }) }) } async fn insert_data(&self, collection_name: String, collection: &[Value]) -> Result<()> { - self.insert_relational_data(collection_name, collection).await + self.insert_relational_data(collection_name, collection) + .await } } diff --git a/synth/src/datasource/postgres_datasource.rs b/synth/src/datasource/postgres_datasource.rs index c90f8910..64f0a2ee 100644 --- a/synth/src/datasource/postgres_datasource.rs +++ b/synth/src/datasource/postgres_datasource.rs @@ -3,12 +3,13 @@ use crate::datasource::relational_datasource::{ }; use crate::datasource::DataSource; use anyhow::{Context, Result}; +use async_std::sync::Arc; use async_std::task; use async_trait::async_trait; use rust_decimal::prelude::ToPrimitive; use rust_decimal::Decimal; use sqlx::postgres::{PgColumn, PgPoolOptions, PgQueryResult, PgRow}; -use sqlx::{Column, Pool, Postgres, Row, TypeInfo, Executor}; +use sqlx::{Column, Executor, Pool, Postgres, Row, TypeInfo}; use std::collections::BTreeMap; use std::convert::TryFrom; use synth_core::schema::number_content::{F32, F64, I32, I64}; @@ -17,11 +18,10 @@ use synth_core::schema::{ StringContent, Uuid, }; use synth_core::{Content, Value}; -use async_std::sync::Arc; pub struct PostgresConnectParams { pub(crate) uri: String, - pub(crate) schema: Option + pub(crate) schema: Option, } pub struct PostgresDataSource { @@ -47,7 +47,8 @@ impl DataSource for PostgresDataSource { .after_connect(move |conn| { let schema = arc.clone(); Box::pin(async move { - conn.execute(&*format!("SET search_path = '{}';", schema)).await?; + conn.execute(&*format!("SET search_path = '{}';", schema)) + .await?; Ok(()) }) }) @@ -58,10 +59,11 @@ impl DataSource for PostgresDataSource { arc = Arc::new(schema.clone()); let single_thread_pool = PgPoolOptions::new() .max_connections(1) - .after_connect(move |conn|{ + .after_connect(move |conn| { let schema = arc.clone(); Box::pin(async move { - conn.execute(&*format!("SET search_path = '{}';", schema)).await?; + conn.execute(&*format!("SET search_path = '{}';", schema)) + .await?; Ok(()) }) }) @@ -74,13 +76,14 @@ impl DataSource for PostgresDataSource { Ok::(PostgresDataSource { pool, single_thread_pool, - schema + schema, }) }) } async fn insert_data(&self, collection_name: String, collection: &[Value]) -> Result<()> { - self.insert_relational_data(collection_name, collection).await + self.insert_relational_data(collection_name, collection) + .await } } @@ -99,7 +102,11 @@ impl PostgresDataSource { if !available_schemas.contains(&schema.to_string()) { let formatted_schemas = available_schemas.join(", "); - bail!("the schema '{}' could not be found on the database. Available schemas are: {}.", schema, formatted_schemas); + bail!( + "the schema '{}' could not be found on the database. Available schemas are: {}.", + schema, + formatted_schemas + ); } Ok(()) @@ -110,7 +117,11 @@ impl PostgresDataSource { impl RelationalDataSource for PostgresDataSource { type QueryResult = PgQueryResult; - async fn execute_query(&self, query: String, query_params: Vec<&Value>) -> Result { + async fn execute_query( + &self, + query: String, + query_params: Vec<&Value>, + ) -> Result { let mut query = sqlx::query(query.as_str()); for param in query_params { diff --git a/synth/src/datasource/relational_datasource.rs b/synth/src/datasource/relational_datasource.rs index 64e42ab2..7739228a 100644 --- a/synth/src/datasource/relational_datasource.rs +++ b/synth/src/datasource/relational_datasource.rs @@ -50,7 +50,6 @@ pub trait RelationalDataSource: DataSource { collection_name: String, collection: &[Value], ) -> Result<()> { - let batch_size = DEFAULT_INSERT_BATCH_SIZE; if collection.is_empty() { @@ -71,18 +70,26 @@ pub trait RelationalDataSource: DataSource { for column_info in column_infos { if let Some(value) = first_valueset.get(&column_info.column_name) { match (value, &*column_info.data_type) { - (Value::Number(Number::U64(_)), "int2" | "int4" | "int8" | "int" | "integer" | "smallint" | "bigint") => - warn!("Trying to put an unsigned u64 into a {} typed column {}.{}", - column_info.data_type, collection_name, column_info.column_name), - (Value::Number(Number::U32(_)), "int2" | "int4" | "int8" | "int" | "integer" | "smallint" | "bigint") => - warn!("Trying to put an unsigned u32 into a {} typed column {}.{}", - column_info.data_type, collection_name, column_info.column_name), + ( + Value::Number(Number::U64(_)), + "int2" | "int4" | "int8" | "int" | "integer" | "smallint" | "bigint", + ) => warn!( + "Trying to put an unsigned u64 into a {} typed column {}.{}", + column_info.data_type, collection_name, column_info.column_name + ), + ( + Value::Number(Number::U32(_)), + "int2" | "int4" | "int8" | "int" | "integer" | "smallint" | "bigint", + ) => warn!( + "Trying to put an unsigned u32 into a {} typed column {}.{}", + column_info.data_type, collection_name, column_info.column_name + ), //TODO: More variants _ => {} } } } - + let column_names = first_valueset .keys() .cloned() @@ -104,7 +111,7 @@ pub trait RelationalDataSource: DataSource { let row_obj = row .as_object() .expect("This is always an object (sampler contract)"); - + let extend = row_obj.values().len(); Self::extend_parameterised_query(&mut query, curr_index, extend); curr_index += extend; @@ -124,7 +131,6 @@ pub trait RelationalDataSource: DataSource { if let Err(e) = results.into_iter().bcollect::>() { bail!("One or more database inserts failed: {:?}", e) - } info!("Inserted {} rows...", collection.len()); @@ -150,7 +156,7 @@ pub trait RelationalDataSource: DataSource { async fn get_deterministic_samples(&self, table_name: &str) -> Result>; fn decode_to_content(&self, data_type: &str, _char_max_len: Option) -> Result; - + // Returns extended query string + current index fn extend_parameterised_query(query: &mut String, curr_index: usize, extend: usize); } diff --git a/synth/src/lib.rs b/synth/src/lib.rs index 6b1c8d14..74be103d 100644 --- a/synth/src/lib.rs +++ b/synth/src/lib.rs @@ -1,4 +1,10 @@ -#![feature(format_args_capture, async_closure, map_first_last, box_patterns, concat_idents)] +#![feature( + format_args_capture, + async_closure, + map_first_last, + box_patterns, + concat_idents +)] #![feature(error_iter)] #![allow(type_alias_bounds)] diff --git a/synth/src/main.rs b/synth/src/main.rs index da9a8c39..266d0434 100644 --- a/synth/src/main.rs +++ b/synth/src/main.rs @@ -1,9 +1,9 @@ use anyhow::Result; +use std::thread; +use std::thread::JoinHandle; use structopt::StructOpt; use synth::cli::Args; use synth::cli::Cli; -use std::thread; -use std::thread::JoinHandle; #[async_std::main] async fn main() -> Result<()> { diff --git a/synth/src/sampler.rs b/synth/src/sampler.rs index 666dcc2f..cb1a26d1 100644 --- a/synth/src/sampler.rs +++ b/synth/src/sampler.rs @@ -1,11 +1,11 @@ use anyhow::Result; use indicatif::{ProgressBar, ProgressStyle}; use rand::SeedableRng; -use synth_core::{Graph, Name, Namespace, Value}; -use synth_core::graph::json::synth_val_to_json; -use synth_gen::prelude::*; use std::collections::BTreeMap; use std::convert::TryFrom; +use synth_core::graph::json::synth_val_to_json; +use synth_core::{Graph, Name, Namespace, Value}; +use synth_gen::prelude::*; pub(crate) struct Sampler { graph: Graph, @@ -13,7 +13,7 @@ pub(crate) struct Sampler { pub(crate) enum SamplerOutput { Namespace(Vec<(String, Vec)>), - Collection(Vec) + Collection(Vec), } impl SamplerOutput { @@ -26,7 +26,7 @@ impl SamplerOutput { .collect(); Value::Object(object) } - Self::Collection(values) => Value::Array(values) + Self::Collection(values) => Value::Array(values), }; synth_val_to_json(as_synth) } @@ -70,20 +70,17 @@ enum SampleStrategy { impl SampleStrategy { fn new(collection_name: Option, target: usize) -> Self { match collection_name { - None => SampleStrategy::Namespace(NamespaceSampleStrategy { - target - }), - Some(name) => SampleStrategy::Collection(CollectionSampleStrategy { - name, - target, - }) + None => SampleStrategy::Namespace(NamespaceSampleStrategy { target }), + Some(name) => SampleStrategy::Collection(CollectionSampleStrategy { name, target }), } } fn sample(self, model: Graph, rng: R) -> Result { match self { SampleStrategy::Namespace(nss) => Ok(SamplerOutput::Namespace(nss.sample(model, rng)?)), - SampleStrategy::Collection(css) => Ok(SamplerOutput::Collection(css.sample(model, rng)?)) + SampleStrategy::Collection(css) => { + Ok(SamplerOutput::Collection(css.sample(model, rng)?)) + } } } } @@ -106,19 +103,18 @@ impl NamespaceSampleStrategy { let mut model = model.aggregate(); while generated < self.target { - // We populate `out` by walking through the collections in the generated - // namespace. We also keep track of the number of `Values` generated - // for the progress bar. + // We populate `out` by walking through the collections in the generated + // namespace. We also keep track of the number of `Values` generated + // for the progress bar. let round_start = generated; let next = model.complete(&mut rng)?; as_object(next)? .into_iter() .try_for_each(|(collection, value)| { - as_array(&collection, value) - .map(|vec| { - generated += vec.len(); - out.entry(collection).or_default().extend(vec); - }) + as_array(&collection, value).map(|vec| { + generated += vec.len(); + out.entry(collection).or_default().extend(vec); + }) })?; progress_bar.set_position(generated as u64); if round_start == generated { @@ -158,15 +154,24 @@ impl CollectionSampleStrategy { while generated < self.target { let round_start = generated; let next = model.complete(&mut rng)?; - let collection_value = as_object(next)?.remove(self.name.as_ref()).ok_or_else(|| { - anyhow!("generated namespace does not have a collection '{}'", self.name) - })?; + let collection_value = + as_object(next)?.remove(self.name.as_ref()).ok_or_else(|| { + anyhow!( + "generated namespace does not have a collection '{}'", + self.name + ) + })?; match collection_value { Value::Array(vec) => { generated += vec.len(); out.extend(vec); } - other => return Err(anyhow!("Was expecting the sampled collection to be an array. Instead found {}", other.type_())) + other => { + return Err(anyhow!( + "Was expecting the sampled collection to be an array. Instead found {}", + other.type_() + )) + } } progress_bar.set_position(generated as u64); if round_start == generated { @@ -184,7 +189,10 @@ impl CollectionSampleStrategy { fn as_object(sample: Value) -> Result> { match sample { Value::Object(obj) => Ok(obj), - other => Err(anyhow!("Was expecting the top-level sample to be an object. Instead found {}", other.type_())) + other => Err(anyhow!( + "Was expecting the top-level sample to be an object. Instead found {}", + other.type_() + )), } } diff --git a/synth/src/version.rs b/synth/src/version.rs index 449aa945..1d78f84c 100644 --- a/synth/src/version.rs +++ b/synth/src/version.rs @@ -1,13 +1,13 @@ +use crate::cli::config; use anyhow::Result; use core::option::Option; use core::option::Option::{None, Some}; use core::result::Result::Ok; use core::time::Duration; +use reqwest::header::USER_AGENT; use semver::Version; use serde_json::map::Map; use serde_json::value::Value; -use reqwest::header::USER_AGENT; -use crate::cli::config; /// This is used when the user does `synth version`. /// It will always display a new version if it exists. @@ -42,7 +42,10 @@ pub fn notify_new_version_message() -> Result> { pub fn version_update_info() -> Result<(Option, Version)> { let current_version = version_semver(); let latest_version = latest_version()?; - Ok((version_update_info_inner(¤t_version, &latest_version), latest_version)) + Ok(( + version_update_info_inner(¤t_version, &latest_version), + latest_version, + )) } pub fn version() -> String { @@ -92,10 +95,16 @@ fn latest_version() -> Result { .map_err(|e| anyhow!("failed to parse latest version semver with error: {}", e)) } -fn version_update_info_inner(current_version: &Version, latest_version: &Version) -> Option { +fn version_update_info_inner( + current_version: &Version, + latest_version: &Version, +) -> Option { if latest_version > current_version { let out_of_date = "\nYour version of synth is out of date."; - let version_compare = format!("The installed version is {} and the latest version is {}.", current_version, latest_version); + let version_compare = format!( + "The installed version is {} and the latest version is {}.", + current_version, latest_version + ); #[cfg(windows)] let install_advice = "You can update by downloading from: https://github.com/getsynth/synth/releases/latest/download/synth-windows-latest-x86_64.exe"; #[cfg(not(windows))] diff --git a/tools/hooks/pre-commit b/tools/hooks/pre-commit new file mode 100755 index 00000000..8689ef6a --- /dev/null +++ b/tools/hooks/pre-commit @@ -0,0 +1,23 @@ +#!/bin/bash -e +declare -a rust_files=() +files=$(git diff-index --name-only HEAD) +echo 'Formatting source files' +for file in $files; do + if [ ! -f "${file}" ]; then + continue + fi + if [[ "${file}" == *.rs ]]; then + rust_files+=("${file}") + fi +done +if [ ${#rust_files[@]} -ne 0 ]; then + command -v rustfmt >/dev/null 2>&1 || { echo >&2 "Rustfmt is required but it's not installed. Aborting."; exit 1; } + $(command -v rustfmt) ${rust_files[@]} & +fi +wait +if [ ${#rust_files[@]} -ne 0 ]; then + git add ${rust_files[@]} + echo "Formatting done, changed files: ${rust_files[@]}" +else + echo "No changes, formatting skipped" +fi