Skip to content

Commit

Permalink
Rearrange impl blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasPickering committed Jun 3, 2024
1 parent 040c56f commit e1eac4c
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 134 deletions.
234 changes: 124 additions & 110 deletions src/collection/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ pub struct Profile {
pub data: IndexMap<String, Template>,
}

impl Profile {
/// Get a presentable name for this profile
pub fn name(&self) -> &str {
self.name.as_deref().unwrap_or(&self.id)
}
}

#[cfg(test)]
impl crate::test_util::Factory for Profile {
fn factory(_: ()) -> Self {
Self {
id: "profile1".into(),
name: None,
data: IndexMap::new(),
}
}
}

#[derive(
Clone,
Debug,
Expand All @@ -65,6 +83,20 @@ pub struct Profile {
)]
pub struct ProfileId(String);

#[cfg(test)]
impl From<&str> for ProfileId {
fn from(value: &str) -> Self {
value.to_owned().into()
}
}

#[cfg(test)]
impl crate::test_util::Factory for ProfileId {
fn factory(_: ()) -> Self {
uuid::Uuid::new_v4().to_string().into()
}
}

/// A gathering of like-minded recipes and/or folders
#[derive(Clone, Debug, Serialize, Deserialize)]
#[cfg_attr(test, derive(PartialEq))]
Expand All @@ -82,6 +114,47 @@ pub struct Folder {
pub children: IndexMap<RecipeId, RecipeNode>,
}

impl Folder {
/// Get a presentable name for this folder
pub fn name(&self) -> &str {
self.name.as_deref().unwrap_or(&self.id)
}
}

#[cfg(test)]
impl crate::test_util::Factory for Folder {
fn factory(_: ()) -> Self {
Self {
id: "folder1".into(),
name: None,
children: IndexMap::new(),
}
}
}

impl Recipe {
/// Get a presentable name for this recipe
pub fn name(&self) -> &str {
self.name.as_deref().unwrap_or(&self.id)
}
}

#[cfg(test)]
impl crate::test_util::Factory for Recipe {
fn factory(_: ()) -> Self {
Self {
id: "recipe1".into(),
name: None,
method: Method::Get,
url: "http://localhost/url".into(),
body: None,
authentication: None,
query: IndexMap::new(),
headers: IndexMap::new(),
}
}
}

/// A definition of how to make a request. This is *not* called `Request` in
/// order to distinguish it from a single instance of an HTTP request. And it's
/// not called `RequestTemplate` because the word "template" has a specific
Expand Down Expand Up @@ -121,6 +194,20 @@ pub struct Recipe {
)]
pub struct RecipeId(String);

#[cfg(test)]
impl From<&str> for RecipeId {
fn from(value: &str) -> Self {
value.to_owned().into()
}
}

#[cfg(test)]
impl crate::test_util::Factory for RecipeId {
fn factory(_: ()) -> Self {
uuid::Uuid::new_v4().to_string().into()
}
}

/// HTTP method. This is duplicated from reqwest's Method so we can enforce
/// the method is valid during deserialization. This is also generally more
/// ergonomic at the cost of some flexibility.
Expand Down Expand Up @@ -152,6 +239,31 @@ pub enum Method {
Trace,
}

/// For serialization
impl From<Method> for String {
fn from(method: Method) -> Self {
method.to_string()
}
}

#[cfg(test)]
impl crate::test_util::Factory for Chain {
fn factory(_: ()) -> Self {
Self {
id: "chain1".into(),
source: ChainSource::Request {
recipe: "recipe1".into(),
trigger: Default::default(),
section: Default::default(),
},
sensitive: false,
selector: None,
content_type: None,
trim: ChainOutputTrim::default(),
}
}
}

/// Shortcut for defining authentication method. If this is defined in addition
/// to the `Authorization` header, that header will end up being included in the
/// request twice.
Expand Down Expand Up @@ -261,6 +373,18 @@ pub enum ChainSource {
},
}

/// Test-only helpers
#[cfg(test)]
impl ChainSource {
/// Build a new [Self::Command] variant from [command, ...args]
pub fn command<const N: usize>(cmd: [&str; N]) -> ChainSource {
ChainSource::Command {
command: cmd.into_iter().map(Template::from).collect(),
stdin: None,
}
}
}

/// The component of the response to use as the chain source
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[cfg_attr(test, derive(PartialEq))]
Expand Down Expand Up @@ -341,79 +465,6 @@ impl crate::test_util::Factory for Collection {
}
}

#[cfg(test)]
impl crate::test_util::Factory for ProfileId {
fn factory(_: ()) -> Self {
uuid::Uuid::new_v4().to_string().into()
}
}

#[cfg(test)]
impl crate::test_util::Factory for RecipeId {
fn factory(_: ()) -> Self {
uuid::Uuid::new_v4().to_string().into()
}
}

impl Profile {
/// Get a presentable name for this profile
pub fn name(&self) -> &str {
self.name.as_deref().unwrap_or(&self.id)
}
}

#[cfg(test)]
impl crate::test_util::Factory for Profile {
fn factory(_: ()) -> Self {
Self {
id: "profile1".into(),
name: None,
data: IndexMap::new(),
}
}
}

impl Folder {
/// Get a presentable name for this folder
pub fn name(&self) -> &str {
self.name.as_deref().unwrap_or(&self.id)
}
}

#[cfg(test)]
impl crate::test_util::Factory for Folder {
fn factory(_: ()) -> Self {
Self {
id: "folder1".into(),
name: None,
children: IndexMap::new(),
}
}
}

impl Recipe {
/// Get a presentable name for this recipe
pub fn name(&self) -> &str {
self.name.as_deref().unwrap_or(&self.id)
}
}

#[cfg(test)]
impl crate::test_util::Factory for Recipe {
fn factory(_: ()) -> Self {
Self {
id: "recipe1".into(),
name: None,
method: Method::Get,
url: "http://localhost/url".into(),
body: None,
authentication: None,
query: IndexMap::new(),
headers: IndexMap::new(),
}
}
}

/// For deserialization
impl TryFrom<String> for Method {
type Error = anyhow::Error;
Expand All @@ -428,40 +479,3 @@ impl TryFrom<String> for Method {
})
}
}

/// For serialization
impl From<Method> for String {
fn from(method: Method) -> Self {
method.to_string()
}
}

#[cfg(test)]
impl crate::test_util::Factory for Chain {
fn factory(_: ()) -> Self {
Self {
id: "chain1".into(),
source: ChainSource::Request {
recipe: "recipe1".into(),
trigger: Default::default(),
section: Default::default(),
},
sensitive: false,
selector: None,
content_type: None,
trim: ChainOutputTrim::default(),
}
}
}

/// Test-only helpers
#[cfg(test)]
impl ChainSource {
/// Build a new [Self::Command] variant from [command, ...args]
pub fn command<const N: usize>(cmd: [&str; N]) -> ChainSource {
ChainSource::Command {
command: cmd.into_iter().map(Template::from).collect(),
stdin: None,
}
}
}
18 changes: 18 additions & 0 deletions src/collection/recipe_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,24 @@ impl<'de> Deserialize<'de> for RecipeTree {
}
}

#[cfg(test)]
impl From<IndexMap<RecipeId, Recipe>> for RecipeTree {
fn from(value: IndexMap<RecipeId, Recipe>) -> Self {
value
.into_iter()
.map(|(id, recipe)| (id, RecipeNode::Recipe(recipe)))
.collect::<IndexMap<_, _>>()
.into()
}
}

#[cfg(test)]
impl From<IndexMap<RecipeId, RecipeNode>> for RecipeTree {
fn from(tree: IndexMap<RecipeId, RecipeNode>) -> Self {
Self::new(tree).expect("Duplicate recipe ID")
}
}

impl RecipeNode {
/// Get the ID of the inner folder or recipe
pub fn id(&self) -> &RecipeId {
Expand Down
25 changes: 1 addition & 24 deletions src/test_util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! General test utilities, that apply to all parts of the program
use crate::{
collection::{HasId, ProfileId, Recipe, RecipeId, RecipeNode, RecipeTree},
collection::HasId,
template::{Prompt, Prompter, Template},
util::ResultExt,
};
Expand Down Expand Up @@ -91,29 +91,6 @@ impl Prompter for TestPrompter {
}
}

// Some helpful conversion implementations
impl From<&str> for ProfileId {
fn from(value: &str) -> Self {
value.to_owned().into()
}
}

impl From<IndexMap<RecipeId, Recipe>> for RecipeTree {
fn from(value: IndexMap<RecipeId, Recipe>) -> Self {
let tree = value
.into_iter()
.map(|(id, recipe)| (id, RecipeNode::Recipe(recipe)))
.collect();
Self::new(tree).expect("Duplicate recipe ID")
}
}

impl From<&str> for RecipeId {
fn from(value: &str) -> Self {
value.to_owned().into()
}
}

impl From<&str> for Template {
fn from(value: &str) -> Self {
value.to_owned().try_into().unwrap()
Expand Down

0 comments on commit e1eac4c

Please sign in to comment.