jinxapi_github/v1_1_4/request/
repos_upload_release_asset.rs

1//! Upload a release asset
2//! 
3//! This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in
4//! the response of the [Create a release endpoint](https://docs.github.com/rest/reference/repos#create-a-release) to upload a release asset.
5//! 
6//! You need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.
7//! 
8//! Most libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: 
9//! 
10//! `application/zip`
11//! 
12//! GitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,
13//! you'll still need to pass your authentication to be able to upload an asset.
14//! 
15//! When an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.
16//! 
17//! **Notes:**
18//! *   GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The "[List assets for a release](https://docs.github.com/rest/reference/repos#list-assets-for-a-release)"
19//! endpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://support.github.com/contact?tags=dotcom-rest-api).
20//! *   If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
21//! 
22//! [API method documentation](https://docs.github.com/rest/reference/repos#upload-a-release-asset)
23
24pub struct Content<Body>
25{
26    body: Body,
27    content_type_value: Option<::std::borrow::Cow<'static, [u8]>>,
28}
29
30impl<Body> Content<Body> {
31    pub fn new(body: Body) -> Self {
32        Self { body, content_type_value: None }
33    }
34
35    #[must_use]
36    pub fn with_content_type(mut self, content_type: impl Into<::std::borrow::Cow<'static, [u8]>>) -> Self {
37        self.content_type_value = Some(content_type.into());
38        self
39    }
40
41    fn content_type(&self) -> Option<&[u8]> {
42        self.content_type_value.as_deref()
43    }
44
45    fn into_body(self) -> Body {
46        self.body
47    }
48}
49
50fn url_string(
51    base_url: &str,
52    p_owner: &str,
53    p_repo: &str,
54    p_release_id: i64,
55    q_name: &str,
56    q_label: ::std::option::Option<&str>,
57) -> Result<String, crate::v1_1_4::ApiError> {
58    let trimmed = if base_url.is_empty() {
59        "https://uploads.github.com"
60    } else {
61        base_url.trim_end_matches('/')
62    };
63    let mut url = String::with_capacity(trimmed.len() + 51);
64    url.push_str(trimmed);
65    url.push_str("/repos/");
66    ::querylizer::Simple::extend(&mut url, &p_owner, false, &::querylizer::encode_path)?;
67    url.push('/');
68    ::querylizer::Simple::extend(&mut url, &p_repo, false, &::querylizer::encode_path)?;
69    url.push_str("/releases/");
70    ::querylizer::Simple::extend(&mut url, &p_release_id, false, &::querylizer::encode_path)?;
71    url.push_str("/assets");
72    url.push('?');
73    ::querylizer::Form::extend(&mut url, "name", &q_name, false, &::querylizer::encode_query)?;
74    if let Some(value) = &q_label {
75        url.push('&');
76        ::querylizer::Form::extend(&mut url, "label", value, false, &::querylizer::encode_query)?;
77    }
78    Ok(url)
79}
80
81#[cfg(feature = "hyper")]
82#[allow(clippy::too_many_arguments)]
83pub fn http_builder(
84    base_url: &str,
85    p_owner: &str,
86    p_repo: &str,
87    p_release_id: i64,
88    q_name: &str,
89    q_label: ::std::option::Option<&str>,
90    h_user_agent: &str,
91    h_accept: ::std::option::Option<&str>,
92) -> Result<::http::request::Builder, crate::v1_1_4::ApiError> {
93    let url = url_string(
94        base_url,
95        p_owner,
96        p_repo,
97        p_release_id,
98        q_name,
99        q_label,
100    )?;
101    let mut builder = ::http::request::Request::post(url);
102    builder = builder.header(
103        "User-Agent",
104        &::querylizer::Simple::to_string(&h_user_agent, false, &::querylizer::passthrough)?
105    );
106    if let Some(value) = &h_accept {
107        builder = builder.header(
108            "Accept",
109            &::querylizer::Simple::to_string(value, false, &::querylizer::passthrough)?
110        );
111    }
112    Ok(builder)
113}
114
115#[cfg(feature = "hyper")]
116pub fn hyper_request(
117    mut builder: ::http::request::Builder,
118    content: Content<::hyper::Body>,
119) -> Result<::http::request::Request<::hyper::Body>, crate::v1_1_4::ApiError>
120{
121    if let Some(content_type) = content.content_type() {
122        builder = builder.header(::http::header::CONTENT_TYPE, content_type);
123    }
124    Ok(builder.body(content.into_body())?)
125}
126
127#[cfg(feature = "hyper")]
128impl From<::hyper::Body> for Content<::hyper::Body> {
129    fn from(body: ::hyper::Body) -> Self {
130        Self::new(body)
131    }
132}
133
134#[cfg(feature = "reqwest")]
135#[allow(clippy::too_many_arguments)]
136pub fn reqwest_builder(
137    base_url: &str,
138    p_owner: &str,
139    p_repo: &str,
140    p_release_id: i64,
141    q_name: &str,
142    q_label: ::std::option::Option<&str>,
143    h_user_agent: &str,
144    h_accept: ::std::option::Option<&str>,
145) -> Result<::reqwest::Request, crate::v1_1_4::ApiError> {
146    let url = url_string(
147        base_url,
148        p_owner,
149        p_repo,
150        p_release_id,
151        q_name,
152        q_label,
153    )?;
154    let reqwest_url = ::reqwest::Url::parse(&url)?;
155    let mut request = ::reqwest::Request::new(::reqwest::Method::POST, reqwest_url);
156    let headers = request.headers_mut();
157    headers.append(
158        "User-Agent",
159        ::querylizer::Simple::to_string(&h_user_agent, false, &::querylizer::passthrough)?.try_into()?
160    );
161    if let Some(value) = &h_accept {
162        headers.append(
163            "Accept",
164            ::querylizer::Simple::to_string(value, false, &::querylizer::passthrough)?.try_into()?
165        );
166    }
167    Ok(request)
168}
169
170#[cfg(feature = "reqwest")]
171pub fn reqwest_request(
172    mut builder: ::reqwest::Request,
173    content: Content<::reqwest::Body>,
174) -> Result<::reqwest::Request, crate::v1_1_4::ApiError> {
175    if let Some(content_type) = content.content_type() {
176        builder.headers_mut().append(
177            ::reqwest::header::HeaderName::from_static("content-type"),
178            ::reqwest::header::HeaderValue::try_from(content_type)?,
179        );
180    }
181    *builder.body_mut() = Some(content.into_body());
182    Ok(builder)
183}
184
185#[cfg(feature = "reqwest")]
186impl From<::reqwest::Body> for Content<::reqwest::Body> {
187    fn from(body: ::reqwest::Body) -> Self {
188        Self::new(body)
189    }
190}
191
192#[cfg(feature = "reqwest-blocking")]
193#[allow(clippy::too_many_arguments)]
194pub fn reqwest_blocking_builder(
195    base_url: &str,
196    p_owner: &str,
197    p_repo: &str,
198    p_release_id: i64,
199    q_name: &str,
200    q_label: ::std::option::Option<&str>,
201    h_user_agent: &str,
202    h_accept: ::std::option::Option<&str>,
203) -> Result<::reqwest::blocking::Request, crate::v1_1_4::ApiError> {
204    let url = url_string(
205        base_url,
206        p_owner,
207        p_repo,
208        p_release_id,
209        q_name,
210        q_label,
211    )?;
212    let reqwest_url = ::reqwest::Url::parse(&url)?;
213    let mut request = ::reqwest::blocking::Request::new(::reqwest::Method::POST, reqwest_url);
214    let headers = request.headers_mut();
215    headers.append(
216        "User-Agent",
217        ::querylizer::Simple::to_string(&h_user_agent, false, &::querylizer::passthrough)?.try_into()?
218    );
219    if let Some(value) = &h_accept {
220        headers.append(
221            "Accept",
222            ::querylizer::Simple::to_string(value, false, &::querylizer::passthrough)?.try_into()?
223        );
224    }
225    Ok(request)
226}
227
228#[cfg(feature = "reqwest-blocking")]
229pub fn reqwest_blocking_request(
230    mut builder: ::reqwest::blocking::Request,
231    content: Content<::reqwest::blocking::Body>,
232) -> Result<::reqwest::blocking::Request, crate::v1_1_4::ApiError> {
233    if let Some(content_type) = content.content_type() {
234        builder.headers_mut().append(
235            ::reqwest::header::HeaderName::from_static("content-type"),
236            ::reqwest::header::HeaderValue::try_from(content_type)?,
237        );
238    }
239    *builder.body_mut() = Some(content.into_body());
240    Ok(builder)
241}
242
243#[cfg(feature = "reqwest-blocking")]
244impl From<::reqwest::blocking::Body> for Content<::reqwest::blocking::Body> {
245    fn from(body: ::reqwest::blocking::Body) -> Self {
246        Self::new(body)
247    }
248}
249
250/// Types for body parameter in [`super::repos_upload_release_asset`]
251pub mod body {
252}