ik-mini 0.2.0-alpha.5

Minimal async API Wrapper for IK | Only Reader/Public API | Extremely minimal.
Documentation
use crate::client::InkittRequestBuilder;
use crate::types::{ChaptersResponse, StoryResponse};
use crate::InkittError;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, RwLock};
use crate::types::StoryResult;

/// Contains methods for story-related API endpoints.
///
/// This client provides access to fetching information about stories, story parts,
/// and their content in various formats.
pub struct StoryClient {
    /// The shared `reqwest` client for making HTTP requests.
    pub(crate) http: reqwest::Client,
    /// A flag indicating whether the main client is authenticated.
    pub(crate) is_authenticated: Arc<AtomicBool>,
    /// The Bearer token stored safely for concurrent access.
    pub(crate) auth_token: Arc<RwLock<Option<String>>>,
}

impl StoryClient {
    /// Returns detailed information about a story.
    ///
    /// # Arguments
    /// * `story_id` - The unique identifier of the story to fetch.
    /// * `fields` - An optional slice of `StoryField` specifying which fields to retrieve.
    ///   If `None`, a comprehensive list of all known fields will be requested by default.
    ///
    /// # Returns
    /// A `Result` containing a `StoryResponse` struct with the story's metadata on success.
    ///
    /// # Errors
    /// Returns a `InkittError` if the network request fails or the API returns an error.
    ///
    /// # Examples
    /// ```no_run
    /// # use Inkitt::{InkittClient, field::StoryField};
    /// # #[tokio::main]
    /// # async fn main() -> Result<(), Inkitt::InkittError> {
    /// let client = InkittClient::new();
    /// let story_id = 12345678; // Example story ID
    ///
    /// let story_info = client.story.get_story_info(story_id).await?;
    ///
    /// println!("Title: {}", story_info.title);
    /// println!("Votes: {}", story_info.vote_count);
    /// # Ok(())
    /// # }
    /// ```
    pub async fn get_story_info(&self, story_id: u64) -> Result<StoryResponse, InkittError> {
        let wrapper: StoryResult = InkittRequestBuilder::new(
            &self.http,
            &self.is_authenticated,
            &self.auth_token,
            reqwest::Method::GET,
            &format!("/2/stories/{}", story_id),
        )
            .execute()
            .await?;

        Ok(wrapper.response)
    }

    /// Returns detailed information about a single story part.
    ///
    /// # Arguments
    /// * `part_id` - The unique identifier of the story part to fetch.
    /// * `fields` - An optional slice of `PartField` specifying which fields to retrieve.
    ///   If `None`, a default set of fields will be requested.
    ///
    /// # Returns
    /// A `Result` containing a `PartResponse` struct with the part's metadata on success.
    ///
    /// # Errors
    /// Returns a `InkittError` if the network request fails or the API returns an error.
    ///
    /// # Examples
    /// ```no_run
    /// # use Inkitt::{InkittClient, field::PartField};
    /// # #[tokio::main]
    /// # async fn main() -> Result<(), Inkitt::InkittError> {
    /// let client = InkittClient::new();
    /// let part_id = 87654321; // Example part ID
    /// let fields = &[PartField::Title, PartField::WordCount];
    ///
    /// let part_info = client.story.get_part_info(part_id, Some(fields)).await?;
    ///
    /// println!("Part Title: {}", part_info.title);
    /// println!("Word Count: {}", part_info.word_count);
    /// # Ok(())
    /// # }
    /// ```
    pub async fn get_all_chapter_info(
        &self,
        story_id: u64,
        include_text: bool,
    ) -> Result<ChaptersResponse, InkittError> {
        let mut builder = InkittRequestBuilder::new(
            &self.http,
            &self.is_authenticated,
            &self.auth_token,
            reqwest::Method::GET,
            &format!("/2/stories/{}/chapters", story_id),
        );

        if include_text {
            builder = builder
                .param("include_text", Some(true))
                .requires_auth();
        }

        builder.execute().await
    }

    // /// Returns detailed information about a single story chapter.
    // ///
    // /// # Arguments
    // /// * `story_id` - The unique identifier of the story id
    // /// * `chapter_id` - The unique identifier of the story part to fetch.
    // /// * `fields` - An optional slice of `PartField` specifying which fields to retrieve.
    // ///   If `None`, a default set of fields will be requested.
    // ///
    // /// # Returns
    // /// A `Result` containing a `PartResponse` struct with the part's metadata on success.
    // ///
    // /// # Errors
    // /// Returns a `InkittError` if the network request fails or the API returns an error.
    // ///
    // /// # Examples
    // /// ```no_run
    // /// # use Inkitt::{InkittClient, field::PartField};
    // /// # #[tokio::main]
    // /// # async fn main() -> Result<(), Inkitt::InkittError> {
    // /// let client = InkittClient::new();
    // /// let part_id = 87654321; // Example part ID
    // /// let fields = &[PartField::Title, PartField::WordCount];
    // ///
    // /// let part_info = client.story.get_part_info(part_id, Some(fields)).await?;
    // ///
    // /// println!("Part Title: {}", part_info.title);
    // /// println!("Word Count: {}", part_info.word_count);
    // /// # Ok(())
    // /// # }
    // /// ```
    // pub async fn get_chapter_info(
    //     &self,
    //     story_id: u64,
    //     chapter_id: u64,
    //     include_text: bool,
    // ) -> Result<ChapterResponse, InkittError> {
    //     let mut builder = InkittRequestBuilder::new(
    //         &self.http,
    //         &self.is_authenticated,
    //         reqwest::Method::GET,
    //         &format!("/2/stories/{}/chapters/{}", story_id, chapter_id),
    //     );
    //
    //     if include_text {
    //         builder = builder
    //             .param("include_text", Some(true))
    //             .requires_auth();
    //     }
    //
    //     builder.execute().await
    // }
}