use super::{ApiClient, ApiResult, MockBackend, VoteDirection};
use fido_types::*;
use uuid::Uuid;
#[derive(Clone)]
pub enum Backend {
Api(ApiClient),
Mock(MockBackend),
}
impl Backend {
pub fn api(base_url: impl Into<String>) -> Self {
Backend::Api(ApiClient::new(base_url))
}
pub fn mock() -> Self {
Backend::Mock(MockBackend::new())
}
pub fn set_session_token(&mut self, token: Option<String>) {
match self {
Backend::Api(client) => client.set_session_token(token),
Backend::Mock(_) => {
}
}
}
pub async fn get_test_users(&self) -> ApiResult<Vec<User>> {
match self {
Backend::Api(client) => client.get_test_users().await,
Backend::Mock(mock) => mock.get_test_users().await,
}
}
pub async fn login(&mut self, username: String) -> ApiResult<LoginResponse> {
match self {
Backend::Api(client) => client.login(username).await,
Backend::Mock(mock) => mock.login(username).await,
}
}
pub async fn validate_session(&self) -> ApiResult<super::client::ValidateSessionResponse> {
match self {
Backend::Api(client) => client.validate_session().await,
Backend::Mock(_) => {
Err(super::ApiError::Api(
"Session validation not supported in demo mode".to_string(),
))
}
}
}
pub async fn logout(&self, session_token: String) -> ApiResult<()> {
match self {
Backend::Api(client) => client.logout(session_token).await,
Backend::Mock(_) => {
Ok(())
}
}
}
pub async fn get_posts(
&self,
limit: Option<i32>,
sort: Option<String>,
hashtag: Option<String>,
username: Option<String>,
) -> ApiResult<Vec<Post>> {
match self {
Backend::Api(client) => client.get_posts(limit, sort, hashtag, username).await,
Backend::Mock(mock) => {
mock.get_posts(limit.map(|l| l as usize), sort, hashtag, username)
.await
}
}
}
pub async fn create_post(&mut self, content: String) -> ApiResult<Post> {
match self {
Backend::Api(client) => client.create_post(content).await,
Backend::Mock(mock) => mock.create_post(content).await,
}
}
pub async fn vote_on_post(
&mut self,
post_id: Uuid,
direction: VoteDirection,
) -> ApiResult<serde_json::Value> {
match self {
Backend::Api(client) => client.vote_on_post(post_id, direction).await,
Backend::Mock(mock) => {
mock.vote_on_post(post_id, direction.to_string()).await?;
Ok(serde_json::json!({}))
}
}
}
pub async fn get_post_by_id(&self, post_id: Uuid) -> ApiResult<Post> {
match self {
Backend::Api(client) => client.get_post_by_id(post_id).await,
Backend::Mock(mock) => {
let posts = mock.get_posts(None, None, None, None).await?;
posts
.into_iter()
.find(|p| p.id == post_id)
.ok_or_else(|| super::ApiError::NotFound("Post not found".to_string()))
}
}
}
pub async fn get_replies(&self, post_id: Uuid) -> ApiResult<Vec<Post>> {
match self {
Backend::Api(client) => client.get_replies(post_id).await,
Backend::Mock(mock) => mock.get_replies(post_id).await,
}
}
pub async fn create_reply(&mut self, post_id: Uuid, content: String) -> ApiResult<Post> {
match self {
Backend::Api(client) => client.create_reply(post_id, content).await,
Backend::Mock(mock) => mock.create_reply(post_id, content).await,
}
}
pub async fn delete_post(&mut self, post_id: Uuid) -> ApiResult<serde_json::Value> {
match self {
Backend::Api(client) => client.delete_post(post_id).await,
Backend::Mock(_) => {
Err(super::ApiError::Api(
"Post deletion not supported in demo mode".to_string(),
))
}
}
}
pub async fn get_profile(&self, user_id: Uuid) -> ApiResult<UserProfile> {
match self {
Backend::Api(client) => client.get_profile(user_id).await,
Backend::Mock(mock) => mock.get_profile(user_id).await,
}
}
pub async fn update_bio(&mut self, user_id: Uuid, bio: String) -> ApiResult<serde_json::Value> {
match self {
Backend::Api(client) => client.update_bio(user_id, bio).await,
Backend::Mock(mock) => {
mock.update_bio(bio).await?;
Ok(serde_json::json!({}))
}
}
}
pub async fn get_conversations(&self) -> ApiResult<Vec<serde_json::Value>> {
match self {
Backend::Api(client) => client.get_conversations().await,
Backend::Mock(mock) => mock.get_conversations().await,
}
}
pub async fn get_conversation(&self, user_id: Uuid) -> ApiResult<Vec<DirectMessage>> {
match self {
Backend::Api(client) => client.get_conversation(user_id).await,
Backend::Mock(mock) => mock.get_conversation(user_id).await,
}
}
pub async fn send_message(
&mut self,
to_username: String,
content: String,
) -> ApiResult<DirectMessage> {
match self {
Backend::Api(client) => client.send_message(to_username, content).await,
Backend::Mock(mock) => mock.send_message(to_username, content).await,
}
}
pub async fn mark_messages_read(&self, user_id: Uuid) -> ApiResult<serde_json::Value> {
match self {
Backend::Api(client) => client.mark_messages_read(user_id).await,
Backend::Mock(_) => {
Ok(serde_json::json!({}))
}
}
}
pub async fn get_config(&self) -> ApiResult<UserConfig> {
match self {
Backend::Api(client) => client.get_config().await,
Backend::Mock(mock) => mock.get_config().await,
}
}
pub async fn update_config(&mut self, request: UpdateConfigRequest) -> ApiResult<UserConfig> {
match self {
Backend::Api(client) => client.update_config(request).await,
Backend::Mock(mock) => {
mock.update_config(
request.color_scheme,
request.sort_order,
request.max_posts_display,
request.emoji_enabled,
)
.await
}
}
}
pub async fn get_followed_hashtags(&self) -> ApiResult<Vec<String>> {
match self {
Backend::Api(client) => client.get_followed_hashtags().await,
Backend::Mock(mock) => mock.get_followed_hashtags().await,
}
}
pub async fn follow_hashtag(&mut self, name: String) -> ApiResult<()> {
match self {
Backend::Api(client) => client.follow_hashtag(name).await,
Backend::Mock(mock) => mock.follow_hashtag(name).await,
}
}
pub async fn get_following_list(&self) -> ApiResult<Vec<super::client::SocialUserInfo>> {
match self {
Backend::Api(client) => client.get_following_list().await,
Backend::Mock(_) => {
Ok(Vec::new())
}
}
}
pub async fn get_followers_list(&self) -> ApiResult<Vec<super::client::SocialUserInfo>> {
match self {
Backend::Api(client) => client.get_followers_list().await,
Backend::Mock(_) => {
Ok(Vec::new())
}
}
}
pub async fn get_mutual_friends_list(&self) -> ApiResult<Vec<super::client::SocialUserInfo>> {
match self {
Backend::Api(client) => client.get_mutual_friends_list().await,
Backend::Mock(_) => {
Ok(Vec::new())
}
}
}
pub async fn search_users(
&self,
query: String,
) -> ApiResult<Vec<super::client::UserSearchResult>> {
match self {
Backend::Api(client) => client.search_users(query).await,
Backend::Mock(_) => {
Ok(Vec::new())
}
}
}
pub async fn github_device_flow(&self) -> ApiResult<super::client::GitHubDeviceFlowResponse> {
match self {
Backend::Api(client) => client.github_device_flow().await,
Backend::Mock(_) => {
Err(super::ApiError::Api(
"GitHub OAuth not supported in demo mode".to_string(),
))
}
}
}
pub async fn github_device_poll(&self, device_code: &str) -> ApiResult<LoginResponse> {
match self {
Backend::Api(client) => client.github_device_poll(device_code).await,
Backend::Mock(_) => {
Err(super::ApiError::Api(
"GitHub OAuth not supported in demo mode".to_string(),
))
}
}
}
}
impl Default for Backend {
fn default() -> Self {
Backend::Api(ApiClient::default())
}
}