mod private
{
use crate::error::{ Result, HuggingFaceError };
use secrecy::ExposeSecret;
use serde::{ Deserialize, Serialize };
use std::fmt;
#[ derive( Clone, Serialize, Deserialize ) ]
pub struct Secret
{
#[ serde( with = "secret_serde" ) ]
inner : secrecy::SecretString,
}
impl Secret
{
#[ inline ]
#[ must_use ]
pub fn new( value : impl Into< String > ) -> Self
{
Self
{
inner : secrecy::SecretString::new( value.into().into() ),
}
}
#[ inline ]
pub fn load_from_env( var_name : &str ) -> Result< Self >
{
let value = std::env::var( var_name )
.map_err( | e | HuggingFaceError::Authentication(
format!( "Environment variable '{var_name}' not found : {e}" )
) )?;
if value.trim().is_empty()
{
return Err( HuggingFaceError::Authentication(
format!( "Environment variable '{var_name}' is empty" )
) );
}
Ok( Self::new( value ) )
}
#[ inline ]
#[ must_use ]
pub fn expose_secret( &self ) -> &str
{
self.inner.expose_secret()
}
#[ inline ]
#[ must_use ]
pub fn is_valid( &self ) -> bool
{
let secret = self.inner.expose_secret();
!secret.trim().is_empty() && secret.len() >= 8
}
#[ inline ]
#[ must_use ]
pub fn len( &self ) -> usize
{
self.inner.expose_secret().len()
}
#[ inline ]
#[ must_use ]
pub fn is_empty( &self ) -> bool
{
self.inner.expose_secret().is_empty()
}
}
impl fmt::Debug for Secret
{
#[ inline ]
fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
{
f.debug_struct( "Secret" )
.field( "inner", &"[REDACTED]" )
.finish()
}
}
impl fmt::Display for Secret
{
#[ inline ]
fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result
{
write!( f, "[REDACTED]" )
}
}
impl From< String > for Secret
{
#[ inline ]
fn from( value : String ) -> Self
{
Self::new( value )
}
}
impl From< &str > for Secret
{
#[ inline ]
fn from( value : &str ) -> Self
{
Self::new( value.to_string() )
}
}
mod secret_serde
{
use serde::{ Deserializer, Serializer, Deserialize };
#[ inline ]
pub fn serialize< S >( _secret : &secrecy::SecretString, serializer : S ) -> Result< S::Ok, S::Error >
where
S : Serializer,
{
serializer.serialize_str( "[REDACTED]" )
}
#[ inline ]
pub fn deserialize< 'de, D >( deserializer : D ) -> Result< secrecy::SecretString, D::Error >
where
D : Deserializer< 'de >,
{
let s = String::deserialize( deserializer )?;
Ok( secrecy::SecretString::new( s.into() ) )
}
}
#[ inline ]
pub fn load_huggingface_api_key() -> Result< Secret >
{
Secret::load_from_env( "HUGGINGFACE_API_KEY" )
}
}
crate::mod_interface!
{
exposed use
{
private::Secret,
private::load_huggingface_api_key,
};
}