Code Refactor with Generics and proper definitions

Good day. I'm working through refactoring some code where I'm constantly repeating a bit of code with different enums. Trying to understand if i can refactor a bit of this code using generics. I know I could probably refactor further, but was just trying to remove this repeating for loop. One refactor at a time, so I can learn with each change.

Repetitive code is in the below for loop of each of the following functions. I have many more of these functions. These were different ways to access an api and restricting the parameters using enums. Order and Transactions are enums that return pairs.

pub fn getorders<T>(&self, account: &str, params: &[Order]) -> T
    where
        RequestBuilder: Execute<T>,
    {
        let mut builder = self.client.get(format!("{}accounts/{}/orders", crate::APIWWW, account));
        for param in params {
            let (k, v) = param.into();
            builder = builder.param(k, v);
        }
        builder.execute()
    }

pub fn gettransactions<T>(&self, account: &str, params: &[Transactions]) -> T
    where
        RequestBuilder: Execute<T>,
    {
        let mut builder = self.client.get(format!("{}accounts/{}/transactions", crate::APIWWW, account));
        for param in params {
            let (k, v) = param.into();
            builder = builder.param(k, v);
        }
        builder.execute()
    }

I'm trying to create something like this:

/// CONCEPTUAL - DOES NOT WORK
fn paramsbuild<T, P>(params: &[T]) -> P
where
    T: IntoIterator,
    P: IntoIterator,
{
    let pairs: Vec::new();
    for param in params {
        let (k, v) = param.into();
        pairs.push((k,v));
    }
    pairs
}

I know I have to put further definition on P but I'm not sure how to go about it. I would use paramsbuild to use with builder.params in all of my functions above (gettransactions and getorders and others) instead of each for loop building the parameters using builder.param.

The builder is from attohttpc library and my_source

What i was trying to match with P assuming its even possible as taken from attohttpc documentation looking at the params function ....

impl<B> RequestBuilder<B>
[src]
[−]
pub fn param<K, V>(self, key: K, value: V) -> Self where
    K: AsRef<str>,
    V: ToString, 
[src]
[−]

Associate a query string parameter to the given value.

The same key can be used multiple times.
pub fn params<P, K, V>(self, pairs: P) -> Self where
    P: IntoIterator,
    P::Item: Borrow<(K, V)>,
    K: AsRef<str>,
    V: ToString, 
[src]
[−]

Associated a list of pairs to query parameters.

The same key can be used multiple times.
Example

attohttpc::get("http://foo.bar").params(&[("p1", "v1"), ("p2", "v2")]);

This seems like a lot to put on here.....so not sure if the request is narrow enough. I can rewrite the question if needed. Thanks for reading.

You can define the item type like this:

fn paramsbuild<T>(params: T)
where
    T: IntoIterator<Item = Order>,
{

I'm not sure what you wanted P to be.

thanks for the suggestion.

I was hoping to keep Order Generic so I can use it with Transaction as well. Both Order and Transaction are just enums that contain pairs.

For P; I was hoping to return it to the parent to use it in the definition of RequestBuilder::params. It shows a function signature as

pub fn params<P, K, V>(self, pairs: P) -> Self where
    P: IntoIterator,
    P::Item: Borrow<(K, V)>,
    K: AsRef<str>,
    V: ToString, 

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.