use std::collections::BTreeMap;
use serde::Deserialize;
use super::TokenStore;
use super::types::{App, OAuth1Token, StoreFile, Token, TokenType};
use crate::error::Result;
#[derive(Debug, Deserialize)]
struct LegacyStore {
oauth2_tokens: Option<BTreeMap<String, Token>>,
#[serde(rename = "oauth1_tokens")]
oauth1_token: Option<Token>,
bearer_token: Option<Token>,
}
#[derive(Debug, Deserialize)]
#[allow(dead_code)] struct TwurlrcProfile {
username: Option<String>,
consumer_key: Option<String>,
consumer_secret: Option<String>,
token: Option<String>,
secret: Option<String>,
}
#[derive(Debug, Deserialize)]
struct TwurlrcConfig {
profiles: Option<BTreeMap<String, BTreeMap<String, TwurlrcProfile>>>,
bearer_tokens: Option<BTreeMap<String, String>>,
}
impl TokenStore {
pub(crate) fn load_from_data(&mut self, data: &[u8]) {
if let Ok(sf) = serde_yaml::from_slice::<StoreFile>(data)
&& !sf.apps.is_empty()
{
self.apps = sf.apps;
self.default_app = sf.default_app;
return;
}
if let Ok(legacy) = serde_json::from_slice::<LegacyStore>(data) {
let app = App {
client_id: String::new(),
client_secret: String::new(),
default_user: String::new(),
oauth2_tokens: legacy.oauth2_tokens.unwrap_or_default(),
oauth1_token: legacy.oauth1_token,
bearer_token: legacy.bearer_token,
};
self.apps.insert("default".to_string(), app);
self.default_app = "default".to_string();
let _ = self.save_to_file();
}
}
pub fn import_from_twurlrc(&mut self, file_path: &std::path::Path) -> Result<()> {
let data = std::fs::read(file_path)?;
let twurlrc: TwurlrcConfig = serde_yaml::from_slice(&data)?;
let app = self.active_app_or_create();
if let Some(profiles) = &twurlrc.profiles {
'outer: for consumer_keys in profiles.values() {
if let Some((consumer_key, profile)) = consumer_keys.iter().next() {
if app.oauth1_token.is_none() {
app.oauth1_token = Some(Token {
token_type: TokenType::Oauth1,
bearer: None,
oauth2: None,
oauth1: Some(OAuth1Token {
access_token: profile.token.clone().unwrap_or_default(),
token_secret: profile.secret.clone().unwrap_or_default(),
consumer_key: consumer_key.clone(),
consumer_secret: profile
.consumer_secret
.clone()
.unwrap_or_default(),
}),
});
}
break 'outer;
}
}
}
if let Some(bearer_tokens) = &twurlrc.bearer_tokens
&& let Some(bearer_token) = bearer_tokens.values().next()
{
app.bearer_token = Some(Token {
token_type: TokenType::Bearer,
bearer: Some(bearer_token.clone()),
oauth2: None,
oauth1: None,
});
}
self.save_to_file()
}
}