Skip to main content

strava_wrapper/filters/
segments.rs

1use crate::models::{DetailedSegment, ExplorerResponse, SummarySegment};
2use crate::query::{
3    get_with_query_and_path, put_json, Endpoint, ErrorWrapper, PathQuery, Query, Sendable, ID,
4};
5use async_trait::async_trait;
6use serde::Serialize;
7use std::collections::HashMap;
8use strava_wrapper_macros::{Endpoint, PathQuery, Query, ID};
9
10#[derive(Debug, Clone, Endpoint, Query, PathQuery)]
11#[must_use = "this request is not executed until you call .send().await"]
12pub struct ExploreSegments {
13    url: String,
14    token: String,
15    path: String,
16    query: Vec<(String, String)>,
17    path_params: Vec<(String, String)>,
18}
19
20impl ExploreSegments {
21    /// Required. A bounding box expressed as `[sw_lat, sw_lng, ne_lat, ne_lng]`.
22    pub fn bounds(mut self, sw_lat: f64, sw_lng: f64, ne_lat: f64, ne_lng: f64) -> Self {
23        self.query.push((
24            "bounds".to_string(),
25            format!("{},{},{},{}", sw_lat, sw_lng, ne_lat, ne_lng),
26        ));
27        self
28    }
29
30    /// Filter by "running" or "riding".
31    pub fn activity_type(mut self, activity_type: &str) -> Self {
32        self.query
33            .push(("activity_type".to_string(), activity_type.to_string()));
34        self
35    }
36
37    pub fn min_cat(mut self, cat: u32) -> Self {
38        self.query.push(("min_cat".to_string(), cat.to_string()));
39        self
40    }
41
42    pub fn max_cat(mut self, cat: u32) -> Self {
43        self.query.push(("max_cat".to_string(), cat.to_string()));
44        self
45    }
46}
47
48#[async_trait]
49impl Sendable<ExplorerResponse> for ExploreSegments {
50    async fn send(self) -> Result<ExplorerResponse, ErrorWrapper> {
51        let token = self.token.clone();
52        get_with_query_and_path(self, &token).await
53    }
54}
55
56#[derive(Debug, Clone, Endpoint, Query, PathQuery, ID)]
57#[must_use = "this request is not executed until you call .send().await"]
58pub struct ListStarredSegments {
59    url: String,
60    token: String,
61    path: String,
62    query: Vec<(String, String)>,
63    path_params: Vec<(String, String)>,
64}
65
66#[async_trait]
67impl Sendable<Vec<SummarySegment>> for ListStarredSegments {
68    async fn send(self) -> Result<Vec<SummarySegment>, ErrorWrapper> {
69        let token = self.token.clone();
70        get_with_query_and_path(self, &token).await
71    }
72}
73
74#[derive(Debug, Clone, Endpoint, Query, PathQuery, ID)]
75#[must_use = "this request is not executed until you call .send().await"]
76pub struct GetSegment {
77    url: String,
78    token: String,
79    path: String,
80    query: Vec<(String, String)>,
81    path_params: Vec<(String, String)>,
82}
83
84#[async_trait]
85impl Sendable<DetailedSegment> for GetSegment {
86    async fn send(self) -> Result<DetailedSegment, ErrorWrapper> {
87        let token = self.token.clone();
88        get_with_query_and_path(self, &token).await
89    }
90}
91
92#[derive(Debug, Clone, Serialize)]
93struct StarSegmentBody {
94    starred: bool,
95}
96
97/// Builder for `PUT /segments/{id}/starred`. `.send()` stars or unstars
98/// the segment based on the `starred` flag.
99#[must_use = "this request is not executed until you call .send().await"]
100pub struct StarSegment {
101    url: String,
102    token: String,
103    id: u64,
104    starred: bool,
105}
106
107impl StarSegment {
108    pub fn new(url: impl Into<String>, token: impl Into<String>, id: u64, starred: bool) -> Self {
109        Self {
110            url: url.into(),
111            token: token.into(),
112            id,
113            starred,
114        }
115    }
116}
117
118#[async_trait]
119impl Sendable<DetailedSegment> for StarSegment {
120    async fn send(self) -> Result<DetailedSegment, ErrorWrapper> {
121        let url = format!("{}/v3/segments/{}/starred", self.url, self.id);
122        put_json(
123            &url,
124            &self.token,
125            &StarSegmentBody {
126                starred: self.starred,
127            },
128        )
129        .await
130    }
131}