use std::fmt::Display;
use std::str::FromStr;
use serde::Deserialize;
use crate::error::{ClientError, Result};
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct CasJWTInfo {
pub cas_url: String, pub exp: u64, pub access_token: String,
}
#[derive(Debug, PartialEq)]
pub enum HFRepoType {
Model,
Dataset,
Space,
}
impl FromStr for HFRepoType {
type Err = ClientError;
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"" => Ok(HFRepoType::Model), "model" | "models" => Ok(HFRepoType::Model),
"dataset" | "datasets" => Ok(HFRepoType::Dataset),
"space" | "spaces" => Ok(HFRepoType::Space),
t => Err(ClientError::InvalidRepoType(t.to_owned())),
}
}
}
impl HFRepoType {
pub fn as_str(&self) -> &str {
match self {
HFRepoType::Model => "model",
HFRepoType::Dataset => "dataset",
HFRepoType::Space => "space",
}
}
}
impl Display for HFRepoType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, PartialEq)]
pub struct RepoInfo {
pub repo_type: HFRepoType,
pub full_name: String,
}
impl RepoInfo {
pub fn try_from(repo_type: &str, repo_id: &str) -> Result<Self> {
Ok(Self {
repo_type: repo_type.parse()?,
full_name: repo_id.into(),
})
}
}
impl Display for RepoInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}/{}", self.repo_type, self.full_name)
}
}
#[cfg(test)]
mod tests {
use anyhow::Result;
use super::CasJWTInfo;
#[test]
fn test_cas_jwt_response_deser() -> Result<()> {
let bytes = r#"{"casUrl":"https://cas-server.xethub.hf.co","exp":1756489133,"accessToken":"ey...jQ"}"#;
let info: CasJWTInfo = serde_json::from_slice(bytes.as_bytes())?;
assert_eq!(info.cas_url, "https://cas-server.xethub.hf.co");
assert_eq!(info.exp, 1756489133);
assert_eq!(info.access_token, "ey...jQ");
Ok(())
}
}