kopuz-utils 0.8.2

A modern, lightweight music player built with Rust and Dioxus.
Documentation
pub fn parse_subsonic_path(path_str: &str) -> Option<(&str, Option<&str>)> {
    let parts: Vec<&str> = path_str.split(':').collect();
    if parts.len() >= 2 {
        let id = parts[1].trim();
        if id.is_empty() {
            return None;
        }
        let tag = if parts.len() >= 3 {
            Some(parts[2])
        } else {
            None
        };
        Some((id, tag))
    } else {
        None
    }
}

pub fn subsonic_image_url_from_path(
    path_str: &str,
    server_url: &str,
    access_token: Option<&str>,
    max_width: u32,
    quality: u32,
) -> Option<String> {
    let (id, tag) = parse_subsonic_path(path_str)?;
    if tag == Some("none") {
        return None;
    }

    if let Some(tag) = tag
        && let Some(url) = decode_embedded_cover_url(tag)
    {
        return Some(url);
    }

    let mut url = reqwest::Url::parse(&format!(
        "{}/rest/getCoverArt.view",
        server_url.trim_end_matches('/')
    ))
    .unwrap_or_else(|_| reqwest::Url::parse("http://127.0.0.1/").unwrap());

    {
        let mut pairs = url.query_pairs_mut();
        pairs.append_pair("id", id);
        pairs.append_pair("size", &max_width.to_string());
        pairs.append_pair("quality", &quality.to_string());
        if let Some(token) = access_token {
            pairs.append_pair("access_token", token);
        }
    }

    Some(url.to_string())
}

fn decode_embedded_cover_url(tag: &str) -> Option<String> {
    let hex = tag.strip_prefix("urlhex_")?;
    if hex.len() % 2 != 0 {
        return None;
    }

    let mut bytes = Vec::with_capacity(hex.len() / 2);
    let chars: Vec<char> = hex.chars().collect();
    let mut i = 0;
    while i < chars.len() {
        let hi = chars[i].to_digit(16)?;
        let lo = chars[i + 1].to_digit(16)?;
        bytes.push(((hi << 4) | lo) as u8);
        i += 2;
    }

    String::from_utf8(bytes).ok()
}