Skip to content

Commit

Permalink
use dependency injection for stdin loader
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeDawkins committed Dec 4, 2020
1 parent 039adf6 commit 5dc753a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/command/graph/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::utils::parsers::{parse_schema_location, SchemaLocation};
pub struct Push {
/// The schema file to push
/// Can pass `-` to use stdin instead of a file
#[structopt(long, short = "s", parse(from_str = parse_schema_location))]
#[structopt(long, short = "s", parse(try_from_str = parse_schema_location))]
#[serde(skip_serializing)]
schema: SchemaLocation,

Expand Down Expand Up @@ -44,7 +44,7 @@ impl Push {
&self.profile_name
);

let schema_document = load_schema_from_flag(&self.schema)?;
let schema_document = load_schema_from_flag(&self.schema, std::io::stdin())?;

tracing::debug!("Schema Document to push:\n{}", &schema_document);

Expand Down
4 changes: 2 additions & 2 deletions src/command/subgraph/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::utils::parsers::{parse_schema_location, SchemaLocation};
pub struct Push {
/// The schema file to push
/// Can pass `-` to use stdin instead of a file
#[structopt(long, short = "s", parse(from_str = parse_schema_location))]
#[structopt(long, short = "s", parse(try_from_str = parse_schema_location))]
#[serde(skip_serializing)]
schema: SchemaLocation,

Expand Down Expand Up @@ -50,7 +50,7 @@ impl Push {
&self.profile_name
);

let schema_document = load_schema_from_flag(&self.schema)?;
let schema_document = load_schema_from_flag(&self.schema, std::io::stdin())?;

tracing::debug!("Schema Document to push:\n{}", &schema_document);

Expand Down
32 changes: 18 additions & 14 deletions src/utils/loaders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,16 @@ use anyhow::{Context, Result};
use std::io::Read;
use std::path::Path;

/// this fn takes either a filepath (e.g. "./schema.graphql") or a `-`
/// indicating stdin and attempts to load sdl from one of those two locations
/// It can fail on loading the file or if stdin can't be read.
pub fn load_schema_from_flag(loc: &SchemaLocation) -> Result<String> {
/// this fn takes 2 args: the first, an enum describing where to look to load
/// a schema - from stdin or a file's PathBuf, and the second, the reference to
/// stdin to load from, should it be needed.
pub fn load_schema_from_flag(loc: &SchemaLocation, mut stdin: impl Read) -> Result<String> {
match loc {
SchemaLocation::Stdin(stdin) => {
SchemaLocation::Stdin => {
let mut buffer = String::new();
stdin.clone()
stdin
.read_to_string(&mut buffer)
.context("Failed while attempting to read SDL from stdin")?;
// let mut buffer = String::new();
// io::stdin()
// .read_to_string(&mut buffer)
// .context("Failed while loading from SDL file")?;
Ok(buffer)
}
SchemaLocation::File(path) => {
Expand Down Expand Up @@ -51,7 +47,7 @@ mod tests {
let test_path = test_file.path().to_path_buf();
let loc = SchemaLocation::File(test_path);

let schema = load_schema_from_flag(&loc).unwrap();
let schema = load_schema_from_flag(&loc, std::io::stdin()).unwrap();
assert_eq!(schema, "type Query { hello: String! }".to_string());
}

Expand All @@ -60,10 +56,18 @@ mod tests {
let empty_path = "./wow.graphql";
let loc = SchemaLocation::File(PathBuf::from(empty_path));

let schema = load_schema_from_flag(&loc);
let schema = load_schema_from_flag(&loc, std::io::stdin());
assert_eq!(schema.is_err(), true);
}

// TODO: can we test stdin?
// would that mean passing _actual_ stdin as a value in the enum?
#[test]
fn load_schema_from_stdin_works() {
// input implements std::io::Read, so it should be a suitable
// replacement for stdin
let input = b"type Query { hello: String! }";
let loc = SchemaLocation::Stdin;

let schema = load_schema_from_flag(&loc, &input[..]).unwrap();
assert_eq!(schema, std::str::from_utf8(input).unwrap());
}
}
47 changes: 20 additions & 27 deletions src/utils/parsers.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,49 @@
use anyhow::Result;
use std::path::PathBuf;

// type Stdin = Box<dyn std::io::Read>;
trait ReadAndDebug: std::io::Read + std::fmt::Debug {
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
}

impl ReadAndDebug for std::io::Stdin {
fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum SchemaLocation {
Stdin(Box<dyn ReadAndDebug>),
Stdin,
File(PathBuf),
}

// Stdin(Box<dyn std::io::Read>),
pub fn parse_schema_location(loc: &str) -> SchemaLocation {
pub fn parse_schema_location(loc: &str) -> Result<SchemaLocation> {
if loc == "-" {
SchemaLocation::Stdin(Box::new(std::io::stdin()))
Ok(SchemaLocation::Stdin)
} else if loc.is_empty() {
Err(anyhow::anyhow!(
"The path provided to find a schema is empty"
))
} else {
let path = PathBuf::from(loc);
SchemaLocation::File(path)
Ok(SchemaLocation::File(path))
}
}

#[cfg(test)]
mod tests {
use super::{parse_schema_location, SchemaLocation};
// use std::path::PathBuf;

#[test]
fn it_correctly_parses_stdin_flag() {
let loc = parse_schema_location("-");
match loc {
SchemaLocation::Stdin(_) => {
assert!(true);
}
SchemaLocation::File(_) => {
panic!("Parsing schema location failed. Should be stdin. Found File");
}
}
assert_eq!(parse_schema_location("-").unwrap(), SchemaLocation::Stdin);
}

#[test]
fn it_correctly_parses_path_option() {
unimplemented!();
let loc = parse_schema_location("./schema.graphql").unwrap();
match loc {
SchemaLocation::File(buf) => {
assert_eq!(buf.to_str().unwrap(), "./schema.graphql");
}
_ => panic!("parsed incorrectly as stdin"),
}
}

#[test]
fn it_errs_with_empty_path() {
unimplemented!();
let loc = parse_schema_location("");
assert!(loc.is_err());
}
}

0 comments on commit 5dc753a

Please sign in to comment.