Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --all-features --target ${{ matrix.platform.target }}
args: --all-features --target ${{ matrix.platform.target }} --workspace --exclude xtask
- name: Tests
if: matrix.platform.target != 'wasm32-unknown-unknown'
uses: actions-rs/cargo@v1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: clippy
args: --all-features -- -Drust-2018-idioms -Dwarnings
args: --all-features -- -Drust-2018-idioms -Drust-2024-compatibility -Dwarnings
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ When updating or adding new parameters and endpoints, make changes directly in t
Once your changes are merged, you can update this project as follows (you can also run tasks individually):

```bash
cargo xtask fetch code-gen
cargo xtask fetch preprocess code-gen
```

This will:
Expand Down
3 changes: 2 additions & 1 deletion openapi-generator-template/lib.mustache
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![allow(unused_imports)]
#![allow(clippy::derivable_impls)]
#![allow(clippy::empty_docs)]
#![allow(clippy::needless_return)]
#![allow(elided_lifetimes_in_paths)]
#![allow(unused_imports)]

pub mod apis;
pub mod models;
53 changes: 16 additions & 37 deletions openapi-generator-template/reqwest/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,23 @@ use super::{Error, configuration, ContentType};
{{#-first}}
/// struct for passing parameters to the method [`{{operationId}}`]
#[derive(Clone, Debug)]
pub struct {{{operationIdCamelCase}}}Params {
pub struct {{{operationIdCamelCase}}}Params{{!
Iterate through ALL parameters in the operation.
Only the requestBody has this extension defined, so it will print "<B>".
The other parameters have nothing, so they will print nothing.
This effectively extract the generic parameter from the requestBody
and places it on the struct definition line.
}}{{#allParams}}
{{{vendorExtensions.x-rust-params-generic-parameter}}}
{{/allParams}} {
{{/-first}}
{{#description}}
/// {{{.}}}
{{/description}}
{{#vendorExtensions.x-rust-type}}
pub {{{paramName}}}: {{{.}}},
{{/vendorExtensions.x-rust-type}}
{{^vendorExtensions.x-rust-type}}
pub {{{paramName}}}: {{!
### Option Start
}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{!
Expand All @@ -30,6 +42,7 @@ pub struct {{{operationIdCamelCase}}}Params {
}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{!
### Comma for next arguement
}}{{^-last}},{{/-last}}
{{/vendorExtensions.x-rust-type}}
{{#-last}}
}

Expand Down Expand Up @@ -94,44 +107,10 @@ pub enum {{{operationIdCamelCase}}}Error {
{{#vendorExtensions.x-group-parameters}}
pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}{{{vendorExtensions.x-rust-generic-parameter}}}(configuration: &configuration::Configuration{{#allParams}}{{#-first}}, {{!
### Params
}}params: &{{{operationIdCamelCase}}}Params{{/-first}}{{/allParams}}{{!
}}params: &{{{operationIdCamelCase}}}Params{{#allParams}}{{{vendorExtensions.x-rust-params-generic-parameter}}}{{/allParams}}{{/-first}}{{/allParams}}{{!
### Function return type
}}) -> Result<{{#vendorExtensions.x-rust-return-type}}{{{.}}}{{/vendorExtensions.x-rust-return-type}}{{^vendorExtensions.x-rust-return-type}}{{#isResponseFile}}{{#supportAsync}}reqwest::Response{{/supportAsync}}{{^supportAsync}}reqwest::blocking::Response{{/supportAsync}}{{/isResponseFile}}{{^isResponseFile}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{{returnType}}}{{/supportMultipleResponses}}{{/isResponseFile}}{{/vendorExtensions.x-rust-return-type}}, Error<{{{operationIdCamelCase}}}Error>> {
{{/vendorExtensions.x-group-parameters}}
{{^vendorExtensions.x-group-parameters}}
pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}{{{vendorExtensions.x-rust-generic-parameter}}}(configuration: &configuration::Configuration, {{#allParams}}{{{paramName}}}: {{!
### Option Start
}}{{^required}}Option<{{/required}}{{#required}}{{#isNullable}}Option<{{/isNullable}}{{/required}}{{!
### &str and Vec<&str>
}}{{#isString}}{{#isArray}}Vec<{{/isArray}}{{^isUuid}}&str{{/isUuid}}{{#isArray}}>{{/isArray}}{{/isString}}{{!
### UUIDs
}}{{#isUuid}}{{#isArray}}Vec<{{/isArray}}&str{{#isArray}}>{{/isArray}}{{/isUuid}}{{!
### Models and primative types
}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}models::{{/isContainer}}{{/isPrimitiveType}}{{{dataType}}}{{/isUuid}}{{/isString}}{{!
### Option End
}}{{^required}}>{{/required}}{{#required}}{{#isNullable}}>{{/isNullable}}{{/required}}{{!
### Comma for next arguement
}}{{^-last}}, {{/-last}}{{/allParams}}{{!
### Function return type
}}) -> Result<{{#vendorExtensions.x-rust-return-type}}{{{vendorExtensions.x-rust-return-type}}}{{/vendorExtensions.x-rust-return-type}}{{^vendorExtensions.x-rust-return-type}}{{!
### Response File Support
}}{{#isResponseFile}}{{#supportAsync}}reqwest::Response{{/supportAsync}}{{^supportAsync}}reqwest::blocking::Response{{/supportAsync}}{{/isResponseFile}}{{!
### Regular Responses
}}{{^isResponseFile}}{{!
### Multi response support
}}{{#supportMultipleResponses}}ResponseContent<{{{operationIdCamelCase}}}Success>{{/supportMultipleResponses}}{{!
### Regular return type
}}{{^supportMultipleResponses}}{{^returnType}}(){{/returnType}}{{{returnType}}}{{{vendorExtensions.x-rust-return-type-generic-parameter}}}{{/supportMultipleResponses}}{{/isResponseFile}}{{/vendorExtensions.x-rust-return-type}}{{!
### Error Type
}}, Error<{{{operationIdCamelCase}}}Error>> {
{{#allParams.0}}
// add a prefix to parameters to efficiently prevent name collisions
{{/allParams.0}}
{{#allParams}}
let {{{vendorExtensions.x-rust-param-identifier}}} = {{{paramName}}};
{{/allParams}}
{{/vendorExtensions.x-group-parameters}}

let uri_str = format!("{}{{{path}}}", configuration.base_path{{#pathParams}}, {{{baseName}}}={{#isString}}crate::apis::urlencode(&{{/isString}}{{{vendorExtensions.x-rust-param-identifier}}}{{^required}}.unwrap(){{/required}}{{#required}}{{#isNullable}}.unwrap(){{/isNullable}}{{/required}}{{#isArray}}.join(",").as_ref(){{/isArray}}{{^isString}}{{^isUuid}}{{^isPrimitiveType}}{{^isContainer}}.to_string(){{/isContainer}}{{/isPrimitiveType}}{{/isUuid}}{{/isString}}{{#isString}}){{/isString}}{{/pathParams}});
let mut req_builder = configuration.client.request(reqwest::Method::{{{httpMethod}}}, &uri_str);

Expand Down Expand Up @@ -513,4 +492,4 @@ pub {{#supportAsync}}async {{/supportAsync}}fn {{{operationId}}}{{{vendorExtensi
}

{{/operation}}
{{/operations}}
{{/operations}}
6 changes: 6 additions & 0 deletions preprocessed_openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ paths:
description: Can be any key-value pair
x-go-type: interface{}
required: true
x-rust-params-generic-parameter: <B>
x-rust-type: B
x-rust-generic-parameter: '<B: Serialize>'
delete:
tags:
- documents
Expand Down Expand Up @@ -1253,6 +1256,8 @@ paths:
description: Can be any key-value pair
x-go-type: interface{}
required: true
x-rust-params-generic-parameter: <B>
x-rust-type: B
responses:
'200':
description: The document referenced by the ID was updated
Expand All @@ -1267,6 +1272,7 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
x-rust-generic-parameter: '<B: Serialize>'
delete:
tags:
- documents
Expand Down
55 changes: 30 additions & 25 deletions typesense/src/client/collection/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! via a parent `Collection` struct, for example:
//! `client.collection::<Book>().document("123")`

use crate::{Client, Error, execute_wrapper};
use crate::{Client, Error, execute_wrapper, traits};
use serde::{Serialize, de::DeserializeOwned};
use typesense_codegen::apis::documents_api;

Expand Down Expand Up @@ -51,10 +51,32 @@ where

let result_value = execute_wrapper!(self, documents_api::get_document, params)?;

// Deserialize the raw JSON value into the user's type T.
// Deserialize the raw JSON value into the user's type D.
serde_json::from_value(result_value).map_err(Error::from)
}

/// Deletes this individual document from the collection.
/// The deleted document is returned.
///
/// # Returns
/// A `Result` containing the deleted document deserialized into `D`.
pub async fn delete(&self) -> Result<D, Error<documents_api::DeleteDocumentError>> {
let params = documents_api::DeleteDocumentParams {
collection_name: self.collection_name.to_owned(),
document_id: self.document_id.to_owned(),
};

let result_value = execute_wrapper!(self, documents_api::delete_document, params)?;

// Deserialize the raw JSON value of the deleted document into T.
serde_json::from_value(result_value).map_err(Error::from)
}
}

impl<'c, 'n, D> Document<'c, 'n, D>
where
D: traits::Document,
{
/// Updates this individual document. The update can be partial.
/// The updated full document is returned.
///
Expand All @@ -68,9 +90,9 @@ where
/// # Example
/// ```no_run
/// # use serde::{Serialize, Deserialize};
/// # use typesense::{Client, models};
/// # use typesense::{Client, Typesense, models};
/// # use reqwest::Url;
/// # #[derive(Serialize, Deserialize)]
/// # #[derive(Typesense, Serialize, Deserialize)]
/// # struct Book { id: String, title: String, pages: i32 }
/// #
/// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
Expand All @@ -79,7 +101,7 @@ where
/// # .api_key("xyz")
/// # .build()
/// # .unwrap();
/// let book_update = serde_json::json!({ "pages": 654 });
/// let book_update = BookPartial { pages: Some(654), ..Default::default() };
///
/// // Simple update
/// let updated_book = client.collection_named::<Book>("books").document("123")
Expand All @@ -97,15 +119,15 @@ where
/// # Ok(())
/// # }
/// ```
pub async fn update<U: Serialize>(
pub async fn update(
&self,
partial_document: U,
partial_document: &D::Partial,
params: Option<crate::models::DocumentIndexParameters>,
) -> Result<D, Error<documents_api::UpdateDocumentError>> {
let params = documents_api::UpdateDocumentParams {
collection_name: self.collection_name.to_owned(),
document_id: self.document_id.to_owned(),
body: serde_json::to_value(partial_document)?,
body: partial_document,
dirty_values: params.and_then(|d| d.dirty_values),
};

Expand All @@ -114,21 +136,4 @@ where
// Deserialize the raw JSON value of the updated document into T.
serde_json::from_value(result_value).map_err(Error::from)
}

/// Deletes this individual document from the collection.
/// The deleted document is returned.
///
/// # Returns
/// A `Result` containing the deleted document deserialized into `D`.
pub async fn delete(&self) -> Result<D, Error<documents_api::DeleteDocumentError>> {
let params = documents_api::DeleteDocumentParams {
collection_name: self.collection_name.to_owned(),
document_id: self.document_id.to_owned(),
};

let result_value = execute_wrapper!(self, documents_api::delete_document, params)?;

// Deserialize the raw JSON value of the deleted document into T.
serde_json::from_value(result_value).map_err(Error::from)
}
}
Loading
Loading