diff --git a/koucha/src/lib.rs b/koucha/src/lib.rs index 4d4a38b..392e221 100644 --- a/koucha/src/lib.rs +++ b/koucha/src/lib.rs @@ -5,12 +5,104 @@ use reqwest::{ }; use rss::Channel as RawChannel; +type Result = std::result::Result>; + +pub struct AdapterOptions { + database_url: String, +} + +impl AdapterOptions { + pub fn new() -> Self { + Self { + database_url: "sqlite:test.db".to_string(), + } + } + + pub fn database_url(mut self, url: &str) -> Self { + self.database_url = url.to_string(); + self + } + + pub async fn create(self) -> Result { + let db = sqlx::sqlite::SqlitePoolOptions::new() + .connect(&self.database_url).await?; + + Ok(Adapter { db }) + } +} + +pub struct Adapter { + db: sqlx::SqlitePool, +} + +impl Adapter { + pub async fn get_all_users(&self) -> Result> { + let users_query = sqlx::query!("SELECT id, name FROM users") + .fetch_all(&self.db).await?; + + let mut all_users: Vec = Vec::with_capacity(users_query.len()); + + for user in users_query { + all_users.push(User { + id: user.id, + name: user.name, + }) + } + + Ok(all_users) + } + + fn get_pool(&self) -> &sqlx::SqlitePool { &self.db } +} + +pub struct User { + id: i64, + name: String, +} + +impl User { + pub async fn get_by_id(adapter: &Adapter, id: i64) -> Result { + let user = sqlx::query!("SELECT name FROM users WHERE id = ?", id) + .fetch_one(adapter.get_pool()).await?; + + Ok(Self { + id: id, + name: user.name, + }) + } + + pub async fn create(adapter: &Adapter, name: &str) -> Result { + let result = sqlx::query!("INSERT INTO users (name) VALUES (?)", name) + .execute(adapter.get_pool()).await?; + + Ok(Self { + id: result.last_insert_rowid(), + name: name.to_string() + }) + } + + pub async fn change_name( + &mut self, adapter: &Adapter, new_name: &str) -> Result<()> { + sqlx::query!( + "UPDATE users SET name = ? WHERE id = ?", + new_name, self.id + ).execute(adapter.get_pool()).await?; + + self.name = new_name.to_string(); + + Ok(()) + } + + pub fn name(&self) -> &str { &self.name } + pub fn id(&self) -> i64 { self.id } +} + pub struct Channel { pub channel: rss::Channel, } pub async fn fetch_channel( - client: &Client, url: T) -> Result> { + client: &Client, url: T) -> Result { let content = client.get(url) .send().await? .bytes().await?;