bytefetch 0.2.0

A Rust library that makes HTTP file downloads easier to implement.
Documentation
use std::sync::atomic::{AtomicU64, Ordering};

use reqwest::header::HeaderValue;

use super::filename_utils;

#[derive(Debug)]
pub struct HttpDownloadInfo {
    filename: String,
    content_length: Option<u64>,
    is_resumable: bool,
    downloaded_bytes: AtomicU64,
}

impl HttpDownloadInfo {
    pub(super) fn default() -> Self {
        Self {
            filename: String::new(),
            content_length: None,
            is_resumable: false,
            downloaded_bytes: AtomicU64::new(0),
        }
    }

    pub(super) fn extract_and_set_filename(
        mut self,
        raw_url: &str,
        content_disposition: &Option<&HeaderValue>,
    ) -> Self {
        self.filename = filename_utils::extract_filename(raw_url, content_disposition);
        self
    }

    pub(super) fn set_filename(mut self, filename: String) -> Self {
        self.filename = filename;
        self
    }

    pub(super) fn extract_and_set_content_length(
        mut self,
        content_length: &Option<&HeaderValue>,
    ) -> Self {
        self.content_length = content_length
            .and_then(|v| v.to_str().ok())
            .and_then(|s| s.parse::<u64>().ok());
        self
    }

    pub(super) fn set_content_length(mut self, content_length: Option<u64>) -> Self {
        self.content_length = content_length;
        self
    }

    pub(super) fn extract_and_set_is_resumable(
        mut self,
        accept_ranges: &Option<&HeaderValue>,
    ) -> Self {
        self.is_resumable = match accept_ranges {
            Some(value) => value.to_str().map_or(false, |s| s == "bytes"),
            None => false,
        };
        self
    }

    pub(super) fn set_is_resumable(mut self, is_resumable: bool) -> Self {
        self.is_resumable = is_resumable;
        self
    }

    pub(super) fn add_to_downloaded_bytes(&self, number: u64) {
        self.downloaded_bytes.fetch_add(number, Ordering::Relaxed);
    }
}

impl HttpDownloadInfo {
    pub fn filename(&self) -> &str {
        &self.filename
    }

    pub fn content_length(&self) -> Option<u64> {
        self.content_length
    }

    pub fn is_resumable(&self) -> bool {
        self.is_resumable
    }

    pub fn downloaded_bytes(&self) -> u64 {
        self.downloaded_bytes.load(Ordering::Relaxed)
    }
}