use serde::{Deserialize, Serialize};
#[allow(dead_code)]
fn is_zero_i32(value: &i32) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_u32(value: &u32) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_i64(value: &i64) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_u64(value: &u64) -> bool { *value == 0 }
#[allow(dead_code)]
fn is_zero_f32(value: &f32) -> bool { *value == 0.0 }
#[allow(dead_code)]
fn is_zero_f64(value: &f64) -> bool { *value == 0.0 }
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AlbumImagesResponse {
#[serde(default)]
pub images: Vec<ImageInfo>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AlbumInfoResponse {
#[serde(default)]
pub name: String,
#[serde(default)]
pub mbid: String,
#[serde(default)]
pub description: String,
#[serde(default)]
pub url: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AlbumRequest {
#[serde(default)]
pub name: String,
#[serde(default)]
pub artist: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ArtistBiographyResponse {
#[serde(default)]
pub biography: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ArtistImagesResponse {
#[serde(default)]
pub images: Vec<ImageInfo>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ArtistMBIDRequest {
#[serde(default)]
pub id: String,
#[serde(default)]
pub name: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ArtistMBIDResponse {
#[serde(default)]
pub mbid: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ArtistRef {
#[serde(default, skip_serializing_if = "String::is_empty")]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ArtistRequest {
#[serde(default)]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ArtistURLResponse {
#[serde(default)]
pub url: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ImageInfo {
#[serde(default)]
pub url: String,
#[serde(default)]
pub size: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SimilarArtistsRequest {
#[serde(default)]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
#[serde(default)]
pub limit: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SimilarArtistsResponse {
#[serde(default)]
pub artists: Vec<ArtistRef>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SimilarSongsByAlbumRequest {
#[serde(default)]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default)]
pub artist: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
#[serde(default)]
pub count: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SimilarSongsByArtistRequest {
#[serde(default)]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
#[serde(default)]
pub count: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SimilarSongsByTrackRequest {
#[serde(default)]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default)]
pub artist: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
#[serde(default)]
pub count: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SimilarSongsResponse {
#[serde(default)]
pub songs: Vec<SongRef>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SongRef {
#[serde(default, skip_serializing_if = "String::is_empty")]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub isrc: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub artist: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub artist_mbid: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub album: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub album_mbid: String,
#[serde(default, skip_serializing_if = "is_zero_f32")]
pub duration: f32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TopSongsRequest {
#[serde(default)]
pub id: String,
#[serde(default)]
pub name: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub mbid: String,
#[serde(default)]
pub count: i32,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TopSongsResponse {
#[serde(default)]
pub songs: Vec<SongRef>,
}
#[derive(Debug)]
pub struct Error {
pub message: String,
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for Error {}
impl Error {
pub fn new(message: impl Into<String>) -> Self {
Self { message: message.into() }
}
}
pub trait ArtistMBIDProvider {
fn get_artist_mbid(&self, req: ArtistMBIDRequest) -> Result<ArtistMBIDResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_artist_mbid {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_artist_mbid(
req: extism_pdk::Json<$crate::metadata::ArtistMBIDRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::ArtistMBIDResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::ArtistMBIDProvider::get_artist_mbid(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait ArtistURLProvider {
fn get_artist_url(&self, req: ArtistRequest) -> Result<ArtistURLResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_artist_url {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_artist_url(
req: extism_pdk::Json<$crate::metadata::ArtistRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::ArtistURLResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::ArtistURLProvider::get_artist_url(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait ArtistBiographyProvider {
fn get_artist_biography(&self, req: ArtistRequest) -> Result<ArtistBiographyResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_artist_biography {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_artist_biography(
req: extism_pdk::Json<$crate::metadata::ArtistRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::ArtistBiographyResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::ArtistBiographyProvider::get_artist_biography(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait SimilarArtistsProvider {
fn get_similar_artists(&self, req: SimilarArtistsRequest) -> Result<SimilarArtistsResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_similar_artists {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_similar_artists(
req: extism_pdk::Json<$crate::metadata::SimilarArtistsRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::SimilarArtistsResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::SimilarArtistsProvider::get_similar_artists(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait ArtistImagesProvider {
fn get_artist_images(&self, req: ArtistRequest) -> Result<ArtistImagesResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_artist_images {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_artist_images(
req: extism_pdk::Json<$crate::metadata::ArtistRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::ArtistImagesResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::ArtistImagesProvider::get_artist_images(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait ArtistTopSongsProvider {
fn get_artist_top_songs(&self, req: TopSongsRequest) -> Result<TopSongsResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_artist_top_songs {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_artist_top_songs(
req: extism_pdk::Json<$crate::metadata::TopSongsRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::TopSongsResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::ArtistTopSongsProvider::get_artist_top_songs(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait AlbumInfoProvider {
fn get_album_info(&self, req: AlbumRequest) -> Result<AlbumInfoResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_album_info {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_album_info(
req: extism_pdk::Json<$crate::metadata::AlbumRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::AlbumInfoResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::AlbumInfoProvider::get_album_info(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait AlbumImagesProvider {
fn get_album_images(&self, req: AlbumRequest) -> Result<AlbumImagesResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_album_images {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_album_images(
req: extism_pdk::Json<$crate::metadata::AlbumRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::AlbumImagesResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::AlbumImagesProvider::get_album_images(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait SimilarSongsByTrackProvider {
fn get_similar_songs_by_track(&self, req: SimilarSongsByTrackRequest) -> Result<SimilarSongsResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_similar_songs_by_track {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_similar_songs_by_track(
req: extism_pdk::Json<$crate::metadata::SimilarSongsByTrackRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::SimilarSongsResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::SimilarSongsByTrackProvider::get_similar_songs_by_track(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait SimilarSongsByAlbumProvider {
fn get_similar_songs_by_album(&self, req: SimilarSongsByAlbumRequest) -> Result<SimilarSongsResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_similar_songs_by_album {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_similar_songs_by_album(
req: extism_pdk::Json<$crate::metadata::SimilarSongsByAlbumRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::SimilarSongsResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::SimilarSongsByAlbumProvider::get_similar_songs_by_album(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}
pub trait SimilarSongsByArtistProvider {
fn get_similar_songs_by_artist(&self, req: SimilarSongsByArtistRequest) -> Result<SimilarSongsResponse, Error>;
}
#[macro_export]
macro_rules! register_metadata_similar_songs_by_artist {
($plugin_type:ty) => {
#[extism_pdk::plugin_fn]
pub fn nd_get_similar_songs_by_artist(
req: extism_pdk::Json<$crate::metadata::SimilarSongsByArtistRequest>
) -> extism_pdk::FnResult<extism_pdk::Json<$crate::metadata::SimilarSongsResponse>> {
let plugin = <$plugin_type>::default();
let result = $crate::metadata::SimilarSongsByArtistProvider::get_similar_songs_by_artist(&plugin, req.into_inner())?;
Ok(extism_pdk::Json(result))
}
};
}