late 0.0.1373

API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema). Request ids: responses carry an X-Request-Id header with the id we log the request under. Quote it when reporting a problem. A valid x-request-id you send is reused as that id.
Documentation
/*
 * Zernio API
 *
 * API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api  Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal.  Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema).  Request ids: responses carry an X-Request-Id header with the id we log the request under. Quote it when reporting a problem. A valid x-request-id you send is reused as that id.
 *
 * The version of the OpenAPI document: 1.575.1
 * Contact: support@zernio.com
 * Generated by: https://openapi-generator.tech
 */

use super::{configuration, ContentType, Error};
use crate::{apis::ResponseContent, models};
use reqwest;
use serde::{de::Error as _, Deserialize, Serialize};

/// struct for typed errors of method [`ask_support_question`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum AskSupportQuestionError {
    Status400(models::ErrorResponse),
    Status401(models::ErrorResponse),
    Status402(models::ErrorResponse),
    Status403(models::ErrorResponse),
    Status404(models::ErrorResponse),
    Status409(models::ErrorResponse),
    Status422(models::ErrorResponse),
    Status429(models::ErrorResponse),
    Status503(models::ErrorResponse),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`get_support_answer`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum GetSupportAnswerError {
    Status400(models::ErrorResponse),
    Status401(models::ErrorResponse),
    Status402(models::ErrorResponse),
    Status403(models::ErrorResponse),
    Status404(models::ErrorResponse),
    UnknownValue(serde_json::Value),
}

/// struct for typed errors of method [`list_support_answers`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ListSupportAnswersError {
    Status400(models::ErrorResponse),
    Status401(models::ErrorResponse),
    Status402(models::ErrorResponse),
    Status403(models::ErrorResponse),
    Status404(models::ErrorResponse),
    UnknownValue(serde_json::Value),
}

/// Asks the Zernio Support Assistant a question about your workspace. Each question starts a run that answers asynchronously.  ### How a run works  1. This returns 202 with a `runId`. 2. The answer arrives through the `support.run.completed` and `support.run.failed` webhooks. `GET /v1/support/runs/{runId}` is the fallback. 3. When the assistant finds a problem on Zernio's side, it opens a support ticket with the team (see `supportTicket` on the run) and the run ends as `needs_human`.  Pass `threadId` to continue an earlier conversation, and `context` to point the assistant at a post, account, profile or a failed request (its `X-Request-Id`).  ### Pricing  You pay per question, once it finishes. The exact amount charged is the run's `costUsd`.  | Question | You pay | | --- | --- | | Typical question | $0.10 to $0.50 | | Most one question can cost | Its `maxCostUsd`: $0.50 to $3, $3 by default | | Handed to the Zernio team (`needs_human`) | Charged like an answered question | | Failed or expired | $0 | | All questions in a UTC month | At most $100 per account |  Near its `maxCostUsd` a run stops investigating and answers with what it found so far, so it never charges more than the cap. With nothing to answer yet, it fails and costs nothing. Charges appear as \"Support API\" on your invoice.  ### Requirements and limits  - Requires an unrestricted API key, usage-based billing and a card on file. - Limits per account: 3 active runs and $100 of runs per UTC month. - Send an Idempotency-Key header to make retries safe.
pub async fn ask_support_question(
    configuration: &configuration::Configuration,
    ask_support_question_request: models::AskSupportQuestionRequest,
    idempotency_key: Option<&str>,
) -> Result<models::AskSupportQuestion202Response, Error<AskSupportQuestionError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_body_ask_support_question_request = ask_support_question_request;
    let p_header_idempotency_key = idempotency_key;

    let uri_str = format!("{}/v1/support/runs", configuration.base_path);
    let mut req_builder = configuration
        .client
        .request(reqwest::Method::POST, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(param_value) = p_header_idempotency_key {
        req_builder = req_builder.header("Idempotency-Key", param_value.to_string());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };
    req_builder = req_builder.json(&p_body_ask_support_question_request);

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AskSupportQuestion202Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::AskSupportQuestion202Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<AskSupportQuestionError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Returns a run started by your team, with the answer once it is ready.  Prefer the `support.run.completed` and `support.run.failed` webhooks. Use this as the fallback, waiting `pollAfterSeconds` between polls.  `costUsd` is the amount billed for the question, never above `maxCostUsd`, and 0 for a failed run (pricing on Ask a support question).
pub async fn get_support_answer(
    configuration: &configuration::Configuration,
    run_id: &str,
) -> Result<models::SupportRun, Error<GetSupportAnswerError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_path_run_id = run_id;

    let uri_str = format!(
        "{}/v1/support/runs/{runId}",
        configuration.base_path,
        runId = crate::apis::urlencode(p_path_run_id)
    );
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SupportRun`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SupportRun`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<GetSupportAnswerError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}

/// Lists the runs of one thread that your team started, with each question and its answer, oldest first.  - Replies from the Zernio team after a support ticket arrive by email and are not included. - Runs are kept for 90 days.  Page through a long thread with `limit` and `cursor`: pass `nextCursor` as `cursor` until it is null.
pub async fn list_support_answers(
    configuration: &configuration::Configuration,
    thread_id: &str,
    limit: Option<i32>,
    cursor: Option<&str>,
) -> Result<models::ListSupportAnswers200Response, Error<ListSupportAnswersError>> {
    // add a prefix to parameters to efficiently prevent name collisions
    let p_query_thread_id = thread_id;
    let p_query_limit = limit;
    let p_query_cursor = cursor;

    let uri_str = format!("{}/v1/support/runs", configuration.base_path);
    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);

    req_builder = req_builder.query(&[("threadId", &p_query_thread_id.to_string())]);
    if let Some(ref param_value) = p_query_limit {
        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
    }
    if let Some(ref param_value) = p_query_cursor {
        req_builder = req_builder.query(&[("cursor", &param_value.to_string())]);
    }
    if let Some(ref user_agent) = configuration.user_agent {
        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
    }
    if let Some(ref token) = configuration.bearer_access_token {
        req_builder = req_builder.bearer_auth(token.to_owned());
    };

    let req = req_builder.build()?;
    let resp = configuration.client.execute(req).await?;

    let status = resp.status();
    let content_type = resp
        .headers()
        .get("content-type")
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/octet-stream");
    let content_type = super::ContentType::from(content_type);

    if !status.is_client_error() && !status.is_server_error() {
        let content = resp.text().await?;
        match content_type {
            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListSupportAnswers200Response`"))),
            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListSupportAnswers200Response`")))),
        }
    } else {
        let content = resp.text().await?;
        let entity: Option<ListSupportAnswersError> = serde_json::from_str(&content).ok();
        Err(Error::ResponseError(ResponseContent {
            status,
            content,
            entity,
        }))
    }
}