From 5d06ec9faff0ce29634b973a908fcd64adfe5035 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Thu, 4 Feb 2021 21:47:22 +0100 Subject: [PATCH] Split into multiple crates --- Cargo.toml | 52 +------ crates/musicus/Cargo.toml | 41 ++++++ crates/musicus/src/config.rs | 2 + {src => crates/musicus/src}/config.rs.in | 0 .../musicus/src}/editors/ensemble.rs | 7 +- .../musicus/src}/editors/instrument.rs | 7 +- {src => crates/musicus/src}/editors/mod.rs | 0 .../musicus/src}/editors/performance.rs | 2 +- {src => crates/musicus/src}/editors/person.rs | 7 +- .../musicus/src}/editors/recording.rs | 10 +- {src => crates/musicus/src}/editors/work.rs | 6 +- .../musicus/src}/editors/work_part.rs | 2 +- .../musicus/src}/editors/work_section.rs | 3 +- .../musicus/src}/import/disc_source.rs | 4 +- .../musicus/src}/import/folder_source.rs | 2 +- .../musicus/src}/import/medium_editor.rs | 6 +- {src => crates/musicus/src}/import/mod.rs | 0 {src => crates/musicus/src}/import/source.rs | 0 .../musicus/src}/import/source_selector.rs | 2 - .../musicus/src}/import/track_editor.rs | 2 +- .../musicus/src}/import/track_selector.rs | 0 .../musicus/src}/import/track_set_editor.rs | 4 +- {src => crates/musicus/src}/macros.rs | 0 {src => crates/musicus/src}/main.rs | 9 -- crates/musicus/src/meson.build | 59 ++++++++ {src => crates/musicus/src}/navigator/mod.rs | 2 +- .../musicus/src}/navigator/window.rs | 9 +- .../musicus/src}/preferences/login.rs | 5 +- .../musicus/src}/preferences/mod.rs | 2 +- .../musicus/src}/preferences/register.rs | 6 +- .../musicus/src}/preferences/server.rs | 2 +- crates/musicus/src/resources.rs | 9 ++ {src => crates/musicus/src}/resources.rs.in | 0 .../musicus/src}/screens/ensemble.rs | 2 +- {src => crates/musicus/src}/screens/mod.rs | 0 {src => crates/musicus/src}/screens/person.rs | 2 +- .../musicus/src}/screens/player_screen.rs | 2 +- .../musicus/src}/screens/recording.rs | 2 +- {src => crates/musicus/src}/screens/work.rs | 2 +- .../musicus/src}/selectors/ensemble.rs | 5 +- .../musicus/src}/selectors/instrument.rs | 5 +- {src => crates/musicus/src}/selectors/mod.rs | 0 .../musicus/src}/selectors/person.rs | 5 +- .../musicus/src}/selectors/recording.rs | 9 +- .../musicus/src}/selectors/selector.rs | 2 +- {src => crates/musicus/src}/selectors/work.rs | 7 +- .../musicus/src}/widgets/button_row.rs | 0 {src => crates/musicus/src}/widgets/editor.rs | 1 - .../musicus/src}/widgets/entry_row.rs | 0 .../src}/widgets/indexed_list_model.rs | 8 +- {src => crates/musicus/src}/widgets/list.rs | 8 -- {src => crates/musicus/src}/widgets/mod.rs | 0 .../musicus/src}/widgets/player_bar.rs | 2 +- .../musicus/src}/widgets/poe_list.rs | 3 +- {src => crates/musicus/src}/widgets/screen.rs | 0 .../musicus/src}/widgets/section.rs | 0 .../musicus/src}/widgets/upload_section.rs | 5 - {src => crates/musicus/src}/window.rs | 8 +- crates/musicus_backend/Cargo.toml | 17 +++ crates/musicus_backend/src/error.rs | 28 ++++ .../musicus_backend/src/lib.rs | 58 ++++++-- .../musicus_backend/src}/library.rs | 3 +- .../musicus_backend/src}/player.rs | 3 +- .../musicus_backend/src}/secure.rs | 3 +- crates/musicus_client/Cargo.toml | 11 ++ .../musicus_client/src}/ensembles.rs | 5 +- .../musicus_client/src}/error.rs | 25 +--- .../musicus_client/src}/instruments.rs | 5 +- .../musicus_client/src/lib.rs | 124 ++++++++-------- .../musicus_client/src}/mediums.rs | 5 +- .../musicus_client/src}/persons.rs | 5 +- .../musicus_client/src}/recordings.rs | 5 +- .../musicus_client/src}/register.rs | 6 +- .../musicus_client/src}/works.rs | 5 +- crates/musicus_database/Cargo.toml | 15 ++ .../musicus_database/diesel.toml | 0 .../musicus_database/src}/ensembles.rs | 10 +- .../musicus_database/src}/error.rs | 8 +- .../musicus_database/src}/instruments.rs | 10 +- .../musicus_database/src/lib.rs | 12 +- .../musicus_database/src}/medium.rs | 27 ++-- .../musicus_database/src}/persons.rs | 10 +- .../musicus_database/src}/recordings.rs | 28 ++-- .../musicus_database/src}/schema.rs | 0 .../musicus_database/src}/thread.rs | 104 +++++++------- .../musicus_database/src}/works.rs | 21 ++- meson.build | 2 +- src/meson.build | 134 ------------------ 88 files changed, 501 insertions(+), 528 deletions(-) create mode 100644 crates/musicus/Cargo.toml create mode 100644 crates/musicus/src/config.rs rename {src => crates/musicus/src}/config.rs.in (100%) rename {src => crates/musicus/src}/editors/ensemble.rs (94%) rename {src => crates/musicus/src}/editors/instrument.rs (94%) rename {src => crates/musicus/src}/editors/mod.rs (100%) rename {src => crates/musicus/src}/editors/performance.rs (98%) rename {src => crates/musicus/src}/editors/person.rs (95%) rename {src => crates/musicus/src}/editors/recording.rs (96%) rename {src => crates/musicus/src}/editors/work.rs (98%) rename {src => crates/musicus/src}/editors/work_part.rs (98%) rename {src => crates/musicus/src}/editors/work_section.rs (96%) rename {src => crates/musicus/src}/import/disc_source.rs (98%) rename {src => crates/musicus/src}/import/folder_source.rs (98%) rename {src => crates/musicus/src}/import/medium_editor.rs (97%) rename {src => crates/musicus/src}/import/mod.rs (100%) rename {src => crates/musicus/src}/import/source.rs (100%) rename {src => crates/musicus/src}/import/source_selector.rs (98%) rename {src => crates/musicus/src}/import/track_editor.rs (98%) rename {src => crates/musicus/src}/import/track_selector.rs (100%) rename {src => crates/musicus/src}/import/track_set_editor.rs (98%) rename {src => crates/musicus/src}/macros.rs (100%) rename {src => crates/musicus/src}/main.rs (86%) create mode 100644 crates/musicus/src/meson.build rename {src => crates/musicus/src}/navigator/mod.rs (99%) rename {src => crates/musicus/src}/navigator/window.rs (87%) rename {src => crates/musicus/src}/preferences/login.rs (95%) rename {src => crates/musicus/src}/preferences/mod.rs (99%) rename {src => crates/musicus/src}/preferences/register.rs (94%) rename {src => crates/musicus/src}/preferences/server.rs (98%) create mode 100644 crates/musicus/src/resources.rs rename {src => crates/musicus/src}/resources.rs.in (100%) rename {src => crates/musicus/src}/screens/ensemble.rs (98%) rename {src => crates/musicus/src}/screens/mod.rs (100%) rename {src => crates/musicus/src}/screens/person.rs (99%) rename {src => crates/musicus/src}/screens/player_screen.rs (99%) rename {src => crates/musicus/src}/screens/recording.rs (98%) rename {src => crates/musicus/src}/screens/work.rs (98%) rename {src => crates/musicus/src}/selectors/ensemble.rs (94%) rename {src => crates/musicus/src}/selectors/instrument.rs (94%) rename {src => crates/musicus/src}/selectors/mod.rs (100%) rename {src => crates/musicus/src}/selectors/person.rs (94%) rename {src => crates/musicus/src}/selectors/recording.rs (96%) rename {src => crates/musicus/src}/selectors/selector.rs (99%) rename {src => crates/musicus/src}/selectors/work.rs (95%) rename {src => crates/musicus/src}/widgets/button_row.rs (100%) rename {src => crates/musicus/src}/widgets/editor.rs (99%) rename {src => crates/musicus/src}/widgets/entry_row.rs (100%) rename {src => crates/musicus/src}/widgets/indexed_list_model.rs (91%) rename {src => crates/musicus/src}/widgets/list.rs (94%) rename {src => crates/musicus/src}/widgets/mod.rs (100%) rename {src => crates/musicus/src}/widgets/player_bar.rs (99%) rename {src => crates/musicus/src}/widgets/poe_list.rs (98%) rename {src => crates/musicus/src}/widgets/screen.rs (100%) rename {src => crates/musicus/src}/widgets/section.rs (100%) rename {src => crates/musicus/src}/widgets/upload_section.rs (92%) rename {src => crates/musicus/src}/window.rs (97%) create mode 100644 crates/musicus_backend/Cargo.toml create mode 100644 crates/musicus_backend/src/error.rs rename src/backend/mod.rs => crates/musicus_backend/src/lib.rs (60%) rename {src/backend => crates/musicus_backend/src}/library.rs (96%) rename {src/backend => crates/musicus_backend/src}/player.rs (99%) rename {src/backend => crates/musicus_backend/src}/secure.rs (97%) create mode 100644 crates/musicus_client/Cargo.toml rename {src/backend/client => crates/musicus_client/src}/ensembles.rs (86%) rename {src/backend => crates/musicus_client/src}/error.rs (53%) rename {src/backend/client => crates/musicus_client/src}/instruments.rs (86%) rename src/backend/client/mod.rs => crates/musicus_client/src/lib.rs (62%) rename {src/backend/client => crates/musicus_client/src}/mediums.rs (92%) rename {src/backend/client => crates/musicus_client/src}/persons.rs (86%) rename {src/backend/client => crates/musicus_client/src}/recordings.rs (87%) rename {src/backend/client => crates/musicus_client/src}/register.rs (91%) rename {src/backend/client => crates/musicus_client/src}/works.rs (87%) create mode 100644 crates/musicus_database/Cargo.toml rename diesel.toml => crates/musicus_database/diesel.toml (100%) rename {src/backend/database => crates/musicus_database/src}/ensembles.rs (77%) rename {src/backend/database => crates/musicus_database/src}/error.rs (82%) rename {src/backend/database => crates/musicus_database/src}/instruments.rs (78%) rename src/backend/database/mod.rs => crates/musicus_database/src/lib.rs (82%) rename {src/backend/database => crates/musicus_database/src}/medium.rs (89%) rename {src/backend/database => crates/musicus_database/src}/persons.rs (82%) rename {src/backend/database => crates/musicus_database/src}/recordings.rs (91%) rename {src/backend/database => crates/musicus_database/src}/schema.rs (100%) rename {src/backend/database => crates/musicus_database/src}/thread.rs (76%) rename {src/backend/database => crates/musicus_database/src}/works.rs (92%) delete mode 100644 src/meson.build diff --git a/Cargo.toml b/Cargo.toml index 0bba97b..c66a4d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,50 +1,2 @@ -[package] -name = "musicus" -version = "0.1.0" -edition = "2018" - -[dependencies] -anyhow = "1.0.33" -async-trait = "0.1.42" -diesel = { version = "1.4.5", features = ["sqlite"] } -diesel_migrations = "1.4.0" -discid = "0.4.4" -fragile = "1.0.0" -futures = "0.3.6" -futures-channel = "0.3.5" -gettext-rs = "0.5.0" -gtk-macros = "0.2.0" -gstreamer = "0.16.4" -gstreamer-player = "0.16.3" -isahc = "0.9.12" -once_cell = "1.5.2" -rand = "0.7.3" -secret-service = "2.0.1" -serde = { version = "1.0.117", features = ["derive"] } -serde_json = "1.0.59" -thiserror = "1.0.23" -uuid = { version = "0.8", features = ["v4"] } - -[dependencies.gdk] -git = "https://github.com/gtk-rs/gtk4-rs/" -package = "gdk4" - -[dependencies.gio] -git = "https://github.com/gtk-rs/gtk-rs/" -features = ["v2_64"] - -[dependencies.glib] -git = "https://github.com/gtk-rs/gtk-rs/" -features = ["v2_64"] - -[dependencies.gtk] -git = "https://github.com/gtk-rs/gtk4-rs" -package = "gtk4" - -[dependencies.libadwaita] -git = "https://gitlab.gnome.org/bilelmoussaoui/libadwaita-rs" -package = "libadwaita" - -[dependencies.pango] -git = "https://github.com/gtk-rs/gtk-rs/" -features = ["v1_44"] +[workspace] +members = ["crates/*"] diff --git a/crates/musicus/Cargo.toml b/crates/musicus/Cargo.toml new file mode 100644 index 0000000..7451c8d --- /dev/null +++ b/crates/musicus/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "musicus" +version = "0.1.0" +edition = "2018" + +[dependencies] +anyhow = "1.0.33" +async-trait = "0.1.42" +discid = "0.4.4" +futures = "0.3.6" +futures-channel = "0.3.5" +gettext-rs = "0.5.0" +gstreamer = "0.16.4" +gtk-macros = "0.2.0" +musicus_backend = { version = "0.1.0", path = "../musicus_backend" } +once_cell = "1.5.2" +rand = "0.7.3" + +[dependencies.gdk] +git = "https://github.com/gtk-rs/gtk4-rs/" +package = "gdk4" + +[dependencies.gio] +git = "https://github.com/gtk-rs/gtk-rs/" +features = ["v2_64"] + +[dependencies.glib] +git = "https://github.com/gtk-rs/gtk-rs/" +features = ["v2_64"] + +[dependencies.gtk] +git = "https://github.com/gtk-rs/gtk4-rs" +package = "gtk4" + +[dependencies.libadwaita] +git = "https://gitlab.gnome.org/bilelmoussaoui/libadwaita-rs" +package = "libadwaita" + +[dependencies.pango] +git = "https://github.com/gtk-rs/gtk-rs/" +features = ["v1_44"] diff --git a/crates/musicus/src/config.rs b/crates/musicus/src/config.rs new file mode 100644 index 0000000..3c866b8 --- /dev/null +++ b/crates/musicus/src/config.rs @@ -0,0 +1,2 @@ +pub static VERSION: &str = "0.1.0"; +pub static LOCALEDIR: &str = "/app/share/locale"; \ No newline at end of file diff --git a/src/config.rs.in b/crates/musicus/src/config.rs.in similarity index 100% rename from src/config.rs.in rename to crates/musicus/src/config.rs.in diff --git a/src/editors/ensemble.rs b/crates/musicus/src/editors/ensemble.rs similarity index 94% rename from src/editors/ensemble.rs rename to crates/musicus/src/editors/ensemble.rs index d69e974..92e19fe 100644 --- a/src/editors/ensemble.rs +++ b/crates/musicus/src/editors/ensemble.rs @@ -1,12 +1,11 @@ -use crate::backend::generate_id; -use crate::backend::{Backend, Ensemble}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::{Editor, EntryRow, Section, UploadSection, Widget}; use anyhow::Result; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; -use std::cell::RefCell; +use musicus_backend::generate_id; +use musicus_backend::Ensemble; use std::rc::Rc; /// A dialog for creating or editing a ensemble. @@ -92,7 +91,7 @@ impl EnsembleEditor { }; if self.upload.get_active() { - self.handle.backend.post_ensemble(&ensemble).await?; + self.handle.backend.cl().post_ensemble(&ensemble).await?; } self.handle.backend.db().update_ensemble(ensemble.clone()).await?; diff --git a/src/editors/instrument.rs b/crates/musicus/src/editors/instrument.rs similarity index 94% rename from src/editors/instrument.rs rename to crates/musicus/src/editors/instrument.rs index 0066c71..4a76273 100644 --- a/src/editors/instrument.rs +++ b/crates/musicus/src/editors/instrument.rs @@ -1,12 +1,11 @@ -use crate::backend::generate_id; -use crate::backend::{Backend, Instrument}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::{Editor, EntryRow, Section, UploadSection, Widget}; use anyhow::Result; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; -use std::cell::RefCell; +use musicus_backend::generate_id; +use musicus_backend::Instrument; use std::rc::Rc; /// A dialog for creating or editing a instrument. @@ -92,7 +91,7 @@ impl InstrumentEditor { }; if self.upload.get_active() { - self.handle.backend.post_instrument(&instrument).await?; + self.handle.backend.cl().post_instrument(&instrument).await?; } self.handle.backend.db().update_instrument(instrument.clone()).await?; diff --git a/src/editors/mod.rs b/crates/musicus/src/editors/mod.rs similarity index 100% rename from src/editors/mod.rs rename to crates/musicus/src/editors/mod.rs diff --git a/src/editors/performance.rs b/crates/musicus/src/editors/performance.rs similarity index 98% rename from src/editors/performance.rs rename to crates/musicus/src/editors/performance.rs index 0a34f4c..3919830 100644 --- a/src/editors/performance.rs +++ b/crates/musicus/src/editors/performance.rs @@ -1,4 +1,3 @@ -use crate::backend::{Backend, Performance, Person, Ensemble, Instrument}; use crate::navigator::{NavigationHandle, Screen}; use crate::selectors::{EnsembleSelector, InstrumentSelector, PersonSelector}; use crate::widgets::{Editor, Section, ButtonRow, Widget}; @@ -6,6 +5,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; +use musicus_backend::{Performance, Person, Ensemble, Instrument}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/editors/person.rs b/crates/musicus/src/editors/person.rs similarity index 95% rename from src/editors/person.rs rename to crates/musicus/src/editors/person.rs index d1c20b4..cab2a13 100644 --- a/src/editors/person.rs +++ b/crates/musicus/src/editors/person.rs @@ -1,12 +1,11 @@ -use crate::backend::generate_id; -use crate::backend::{Backend, Person}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::{Editor, EntryRow, Section, UploadSection, Widget}; use anyhow::Result; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; -use std::cell::RefCell; +use musicus_backend::generate_id; +use musicus_backend::Person; use std::rc::Rc; /// A dialog for creating or editing a person. @@ -101,7 +100,7 @@ impl PersonEditor { }; if self.upload.get_active() { - self.handle.backend.post_person(&person).await?; + self.handle.backend.cl().post_person(&person).await?; } self.handle.backend.db().update_person(person.clone()).await?; diff --git a/src/editors/recording.rs b/crates/musicus/src/editors/recording.rs similarity index 96% rename from src/editors/recording.rs rename to crates/musicus/src/editors/recording.rs index d930af1..c50cfc9 100644 --- a/src/editors/recording.rs +++ b/crates/musicus/src/editors/recording.rs @@ -1,7 +1,5 @@ use super::performance::PerformanceEditor; -use crate::backend::generate_id; -use crate::backend::{Backend, Performance, Person, Recording, Work}; -use crate::selectors::{PersonSelector, WorkSelector}; +use crate::selectors::WorkSelector; use crate::widgets::{List, Widget}; use crate::navigator::{NavigationHandle, Screen}; use anyhow::Result; @@ -10,6 +8,8 @@ use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::generate_id; +use musicus_backend::{Performance, Recording, Work}; use std::cell::RefCell; use std::rc::Rc; @@ -173,7 +173,7 @@ impl Screen, Recording> for RecordingEditor { } impl RecordingEditor { - /// Update the UI according to work. + /// Update the UI according to work. fn work_selected(&self, work: &Work) { self.work_row.set_title(Some(&gettext("Work"))); self.work_row.set_subtitle(Some(&work.get_title())); @@ -195,7 +195,7 @@ impl RecordingEditor { let upload = self.upload_switch.get_active(); if upload { - self.handle.backend.post_recording(&recording).await?; + self.handle.backend.cl().post_recording(&recording).await?; } self.handle.backend diff --git a/src/editors/work.rs b/crates/musicus/src/editors/work.rs similarity index 98% rename from src/editors/work.rs rename to crates/musicus/src/editors/work.rs index 72f96d4..3068770 100644 --- a/src/editors/work.rs +++ b/crates/musicus/src/editors/work.rs @@ -1,6 +1,4 @@ use super::work_part::WorkPartEditor; -use crate::backend::generate_id; -use crate::backend::{Instrument, Person, Work, WorkPart, WorkSection}; use super::work_section::WorkSectionEditor; use crate::selectors::{InstrumentSelector, PersonSelector}; use crate::navigator::{NavigationHandle, Screen}; @@ -11,6 +9,8 @@ use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::generate_id; +use musicus_backend::{Instrument, Person, Work, WorkPart, WorkSection}; use std::cell::RefCell; use std::convert::TryInto; use std::rc::Rc; @@ -336,7 +336,7 @@ impl WorkEditor { let upload = self.upload_switch.get_active(); if upload { - self.handle.backend.post_work(&work).await?; + self.handle.backend.cl().post_work(&work).await?; } self.handle.backend diff --git a/src/editors/work_part.rs b/crates/musicus/src/editors/work_part.rs similarity index 98% rename from src/editors/work_part.rs rename to crates/musicus/src/editors/work_part.rs index d7ee726..2ae7bac 100644 --- a/src/editors/work_part.rs +++ b/crates/musicus/src/editors/work_part.rs @@ -1,4 +1,3 @@ -use crate::backend::{Person, WorkPart}; use crate::selectors::PersonSelector; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; @@ -7,6 +6,7 @@ use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::{Person, WorkPart}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/editors/work_section.rs b/crates/musicus/src/editors/work_section.rs similarity index 96% rename from src/editors/work_section.rs rename to crates/musicus/src/editors/work_section.rs index b474037..dd29a16 100644 --- a/src/editors/work_section.rs +++ b/crates/musicus/src/editors/work_section.rs @@ -1,10 +1,9 @@ -use crate::backend::WorkSection; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; -use std::cell::RefCell; +use musicus_backend::WorkSection; use std::rc::Rc; /// A dialog for creating or editing a work section. diff --git a/src/import/disc_source.rs b/crates/musicus/src/import/disc_source.rs similarity index 98% rename from src/import/disc_source.rs rename to crates/musicus/src/import/disc_source.rs index 49707e5..c283140 100644 --- a/src/import/disc_source.rs +++ b/crates/musicus/src/import/disc_source.rs @@ -146,8 +146,8 @@ impl Source for DiscSource { let (discid, tracks) = receiver.await??; - self.discid.set(discid); - self.tracks.set(tracks); + self.discid.set(discid).unwrap(); + self.tracks.set(tracks).unwrap(); Ok(()) } diff --git a/src/import/folder_source.rs b/crates/musicus/src/import/folder_source.rs similarity index 98% rename from src/import/folder_source.rs rename to crates/musicus/src/import/folder_source.rs index b0637d5..89e5adc 100644 --- a/src/import/folder_source.rs +++ b/crates/musicus/src/import/folder_source.rs @@ -68,7 +68,7 @@ impl Source for FolderSource { }); let tracks = receiver.await??; - self.tracks.set(tracks); + self.tracks.set(tracks).unwrap(); Ok(()) } diff --git a/src/import/medium_editor.rs b/crates/musicus/src/import/medium_editor.rs similarity index 97% rename from src/import/medium_editor.rs rename to crates/musicus/src/import/medium_editor.rs index 83b5b38..358b5f6 100644 --- a/src/import/medium_editor.rs +++ b/crates/musicus/src/import/medium_editor.rs @@ -1,7 +1,5 @@ use super::source::Source; use super::track_set_editor::{TrackSetData, TrackSetEditor}; -use crate::backend::generate_id; -use crate::backend::{Backend, Medium, Track, TrackSet}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::{List, Widget}; use anyhow::{anyhow, Result}; @@ -10,6 +8,8 @@ use glib::prelude::*; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::generate_id; +use musicus_backend::{Medium, Track, TrackSet}; use std::cell::RefCell; use std::rc::Rc; @@ -192,7 +192,7 @@ impl MediumEditor { let upload = self.publish_switch.get_active(); if upload { - self.handle.backend.post_medium(&medium).await?; + self.handle.backend.cl().post_medium(&medium).await?; } self.handle.backend diff --git a/src/import/mod.rs b/crates/musicus/src/import/mod.rs similarity index 100% rename from src/import/mod.rs rename to crates/musicus/src/import/mod.rs diff --git a/src/import/source.rs b/crates/musicus/src/import/source.rs similarity index 100% rename from src/import/source.rs rename to crates/musicus/src/import/source.rs diff --git a/src/import/source_selector.rs b/crates/musicus/src/import/source_selector.rs similarity index 98% rename from src/import/source_selector.rs rename to crates/musicus/src/import/source_selector.rs index 49e2703..7f87d29 100644 --- a/src/import/source_selector.rs +++ b/crates/musicus/src/import/source_selector.rs @@ -2,14 +2,12 @@ use super::medium_editor::MediumEditor; use super::disc_source::DiscSource; use super::folder_source::FolderSource; use super::source::Source; -use crate::backend::Backend; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; -use std::cell::RefCell; use std::path::PathBuf; use std::rc::Rc; diff --git a/src/import/track_editor.rs b/crates/musicus/src/import/track_editor.rs similarity index 98% rename from src/import/track_editor.rs rename to crates/musicus/src/import/track_editor.rs index a7219dd..c3b63cb 100644 --- a/src/import/track_editor.rs +++ b/crates/musicus/src/import/track_editor.rs @@ -1,10 +1,10 @@ -use crate::backend::Recording; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::Recording; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/import/track_selector.rs b/crates/musicus/src/import/track_selector.rs similarity index 100% rename from src/import/track_selector.rs rename to crates/musicus/src/import/track_selector.rs diff --git a/src/import/track_set_editor.rs b/crates/musicus/src/import/track_set_editor.rs similarity index 98% rename from src/import/track_set_editor.rs rename to crates/musicus/src/import/track_set_editor.rs index 30d62df..23c6023 100644 --- a/src/import/track_set_editor.rs +++ b/crates/musicus/src/import/track_set_editor.rs @@ -1,15 +1,15 @@ use super::source::Source; use super::track_editor::TrackEditor; use super::track_selector::TrackSelector; -use crate::backend::{Backend, Recording}; use crate::navigator::{NavigationHandle, Screen}; -use crate::selectors::{PersonSelector, RecordingSelector}; +use crate::selectors::RecordingSelector; use crate::widgets::{List, Widget}; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::Recording; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/macros.rs b/crates/musicus/src/macros.rs similarity index 100% rename from src/macros.rs rename to crates/musicus/src/macros.rs diff --git a/src/main.rs b/crates/musicus/src/main.rs similarity index 86% rename from src/main.rs rename to crates/musicus/src/main.rs index 0c945ea..a851c7d 100644 --- a/src/main.rs +++ b/crates/musicus/src/main.rs @@ -1,11 +1,3 @@ -// Required for database/schema.rs -#[macro_use] -extern crate diesel; - -// Required for embed_migrations macro in database/database.rs -#[macro_use] -extern crate diesel_migrations; - use gio::prelude::*; use glib::clone; use std::cell::RefCell; @@ -14,7 +6,6 @@ use std::rc::Rc; #[macro_use] mod macros; -mod backend; mod config; mod editors; mod import; diff --git a/crates/musicus/src/meson.build b/crates/musicus/src/meson.build new file mode 100644 index 0000000..0ab38c2 --- /dev/null +++ b/crates/musicus/src/meson.build @@ -0,0 +1,59 @@ +prefix = get_option('prefix') +localedir = join_paths(prefix, get_option('localedir')) + +global_conf = configuration_data() +global_conf.set_quoted('LOCALEDIR', localedir) +global_conf.set_quoted('VERSION', meson.project_version()) +config_rs = configure_file( + input: 'config.rs.in', + output: 'config.rs', + configuration: global_conf +) + +run_command( + 'cp', + config_rs, + meson.current_source_dir(), + check: true +) + +resource_conf = configuration_data() +resource_conf.set_quoted('RESOURCEFILE', resources.full_path()) +resource_rs = configure_file( + input: 'resources.rs.in', + output: 'resources.rs', + configuration: resource_conf +) + +run_command( + 'cp', + resource_rs, + meson.current_source_dir(), + check: true +) + +sources = files( + 'config.rs', + 'resources.rs', +) + +cargo_script = find_program(join_paths(meson.source_root(), 'build-aux/cargo.sh')) +cargo_release = custom_target( + 'cargo-build', + build_by_default: true, + input: sources, + build_always_stale: true, + depends: resources, + output: meson.project_name(), + console: true, + install: true, + install_dir: get_option('bindir'), + command: [ + cargo_script, + meson.build_root(), + meson.source_root(), + '@OUTPUT@', + get_option('buildtype'), + meson.project_name(), + ] +) diff --git a/src/navigator/mod.rs b/crates/musicus/src/navigator/mod.rs similarity index 99% rename from src/navigator/mod.rs rename to crates/musicus/src/navigator/mod.rs index 70b434a..26eb898 100644 --- a/src/navigator/mod.rs +++ b/crates/musicus/src/navigator/mod.rs @@ -1,9 +1,9 @@ -use crate::backend::Backend; use crate::widgets::Widget; use futures_channel::oneshot; use futures_channel::oneshot::{Receiver, Sender}; use glib::clone; use gtk::prelude::*; +use musicus_backend::Backend; use std::cell::{Cell, RefCell}; use std::rc::{Rc, Weak}; diff --git a/src/navigator/window.rs b/crates/musicus/src/navigator/window.rs similarity index 87% rename from src/navigator/window.rs rename to crates/musicus/src/navigator/window.rs index 4c12486..6440650 100644 --- a/src/navigator/window.rs +++ b/crates/musicus/src/navigator/window.rs @@ -1,7 +1,7 @@ -use crate::backend::Backend; -use super::{Navigator, Screen}; +use super::Navigator; use glib::clone; use gtk::prelude::*; +use musicus_backend::Backend; use std::rc::Rc; /// A window hosting a navigator. @@ -35,9 +35,4 @@ impl NavigatorWindow { self.window.set_modal(true); self.window.set_transient_for(Some(window)); } - - /// Show the navigator window. - pub fn show(&self) { - self.window.show(); - } } diff --git a/src/preferences/login.rs b/crates/musicus/src/preferences/login.rs similarity index 95% rename from src/preferences/login.rs rename to crates/musicus/src/preferences/login.rs index 452e77d..51abe50 100644 --- a/src/preferences/login.rs +++ b/crates/musicus/src/preferences/login.rs @@ -1,12 +1,11 @@ use super::register::RegisterDialog; use crate::push; -use crate::backend::{Backend, LoginData}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; -use std::cell::RefCell; +use musicus_backend::LoginData; use std::rc::Rc; /// A dialog for entering login credentials. @@ -55,7 +54,7 @@ impl Screen<(), LoginData> for LoginDialog { spawn!(@clone this, async move { this.handle.backend.set_login_data(data.clone()).await.unwrap(); - if this.handle.backend.login().await.unwrap() { + if this.handle.backend.cl().login().await.unwrap() { this.handle.pop(Some(data)); } else { this.widget.set_visible_child_name("content"); diff --git a/src/preferences/mod.rs b/crates/musicus/src/preferences/mod.rs similarity index 99% rename from src/preferences/mod.rs rename to crates/musicus/src/preferences/mod.rs index f5526d6..81972db 100644 --- a/src/preferences/mod.rs +++ b/crates/musicus/src/preferences/mod.rs @@ -1,9 +1,9 @@ -use crate::backend::Backend; use crate::navigator::NavigatorWindow; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; +use musicus_backend::Backend; use libadwaita::prelude::*; use std::rc::Rc; diff --git a/src/preferences/register.rs b/crates/musicus/src/preferences/register.rs similarity index 94% rename from src/preferences/register.rs rename to crates/musicus/src/preferences/register.rs index 6ae1d81..889c311 100644 --- a/src/preferences/register.rs +++ b/crates/musicus/src/preferences/register.rs @@ -1,10 +1,10 @@ -use crate::backend::{Backend, LoginData, UserRegistration}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::{LoginData, UserRegistration}; use std::cell::RefCell; use std::rc::Rc; @@ -85,7 +85,7 @@ impl Screen<(), LoginData> for RegisterDialog { }; // TODO: Handle errors. - if this.handle.backend.register(registration).await.unwrap() { + if this.handle.backend.cl().register(registration).await.unwrap() { let data = LoginData { username, password, @@ -102,7 +102,7 @@ impl Screen<(), LoginData> for RegisterDialog { // Initialize spawn!(@clone this, async move { - let captcha = this.handle.backend.get_captcha().await.unwrap(); + let captcha = this.handle.backend.cl().get_captcha().await.unwrap(); this.captcha_row.set_title(Some(&captcha.question)); this.captcha_id.replace(Some(captcha.id)); this.widget.set_visible_child_name("content"); diff --git a/src/preferences/server.rs b/crates/musicus/src/preferences/server.rs similarity index 98% rename from src/preferences/server.rs rename to crates/musicus/src/preferences/server.rs index cb024ae..2775b97 100644 --- a/src/preferences/server.rs +++ b/crates/musicus/src/preferences/server.rs @@ -1,7 +1,7 @@ -use crate::backend::Backend; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; +use musicus_backend::Backend; use std::cell::RefCell; use std::rc::Rc; diff --git a/crates/musicus/src/resources.rs b/crates/musicus/src/resources.rs new file mode 100644 index 0000000..9629008 --- /dev/null +++ b/crates/musicus/src/resources.rs @@ -0,0 +1,9 @@ +use anyhow::Result; + +pub fn init() -> Result<()> { + let bytes = glib::Bytes::from(include_bytes!("/home/johrpan/.var/app/org.gnome.Builder/cache/gnome-builder/projects/musicus/builds/de.johrpan.musicus.json-flatpak-org.gnome.Platform-x86_64-master-error-handling/res/musicus.gresource").as_ref()); + let resource = gio::Resource::from_data(&bytes)?; + gio::resources_register(&resource); + + Ok(()) +} diff --git a/src/resources.rs.in b/crates/musicus/src/resources.rs.in similarity index 100% rename from src/resources.rs.in rename to crates/musicus/src/resources.rs.in diff --git a/src/screens/ensemble.rs b/crates/musicus/src/screens/ensemble.rs similarity index 98% rename from src/screens/ensemble.rs rename to crates/musicus/src/screens/ensemble.rs index ac90cf2..7081521 100644 --- a/src/screens/ensemble.rs +++ b/crates/musicus/src/screens/ensemble.rs @@ -1,5 +1,4 @@ use super::RecordingScreen; -use crate::backend::{Backend, Ensemble, Recording}; use crate::editors::EnsembleEditor; use crate::navigator::{NavigatorWindow, NavigationHandle, Screen}; use crate::widgets; @@ -8,6 +7,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; +use musicus_backend::{Ensemble, Recording}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/screens/mod.rs b/crates/musicus/src/screens/mod.rs similarity index 100% rename from src/screens/mod.rs rename to crates/musicus/src/screens/mod.rs diff --git a/src/screens/person.rs b/crates/musicus/src/screens/person.rs similarity index 99% rename from src/screens/person.rs rename to crates/musicus/src/screens/person.rs index 2b55f08..b563a17 100644 --- a/src/screens/person.rs +++ b/crates/musicus/src/screens/person.rs @@ -1,5 +1,4 @@ use super::{WorkScreen, RecordingScreen}; -use crate::backend::{Backend, Person, Recording, Work}; use crate::editors::PersonEditor; use crate::navigator::{NavigatorWindow, NavigationHandle, Screen}; use crate::widgets; @@ -8,6 +7,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; +use musicus_backend::{Person, Recording, Work}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/screens/player_screen.rs b/crates/musicus/src/screens/player_screen.rs similarity index 99% rename from src/screens/player_screen.rs rename to crates/musicus/src/screens/player_screen.rs index 3bab8c9..dc40fb7 100644 --- a/src/screens/player_screen.rs +++ b/crates/musicus/src/screens/player_screen.rs @@ -1,10 +1,10 @@ -use crate::backend::{Player, PlaylistItem}; use crate::widgets::*; use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::{Player, PlaylistItem}; use std::cell::{Cell, RefCell}; use std::rc::Rc; diff --git a/src/screens/recording.rs b/crates/musicus/src/screens/recording.rs similarity index 98% rename from src/screens/recording.rs rename to crates/musicus/src/screens/recording.rs index 8c6d4a2..251e046 100644 --- a/src/screens/recording.rs +++ b/crates/musicus/src/screens/recording.rs @@ -1,4 +1,3 @@ -use crate::backend::{Backend, PlaylistItem, Recording, TrackSet}; use crate::editors::RecordingEditor; use crate::navigator::{NavigatorWindow, NavigationHandle, Screen}; use crate::widgets; @@ -7,6 +6,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; +use musicus_backend::{PlaylistItem, Recording, TrackSet}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/screens/work.rs b/crates/musicus/src/screens/work.rs similarity index 98% rename from src/screens/work.rs rename to crates/musicus/src/screens/work.rs index 1e3dcc6..2dbc97e 100644 --- a/src/screens/work.rs +++ b/crates/musicus/src/screens/work.rs @@ -1,5 +1,4 @@ use super::RecordingScreen; -use crate::backend::{Backend, Work, Recording}; use crate::editors::WorkEditor; use crate::navigator::{NavigatorWindow, NavigationHandle, Screen}; use crate::widgets; @@ -8,6 +7,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; +use musicus_backend::{Work, Recording}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/selectors/ensemble.rs b/crates/musicus/src/selectors/ensemble.rs similarity index 94% rename from src/selectors/ensemble.rs rename to crates/musicus/src/selectors/ensemble.rs index 3b0bcad..b45ac3e 100644 --- a/src/selectors/ensemble.rs +++ b/crates/musicus/src/selectors/ensemble.rs @@ -1,5 +1,4 @@ use super::selector::Selector; -use crate::backend::{Backend, Ensemble}; use crate::editors::EnsembleEditor; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; @@ -7,7 +6,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; -use std::cell::RefCell; +use musicus_backend::Ensemble; use std::rc::Rc; /// A screen for selecting a ensemble. @@ -45,7 +44,7 @@ impl Screen<(), Ensemble> for EnsembleSelector { this.selector.set_load_online(clone!(@weak this => move || { let clone = this.clone(); - async move { clone.handle.backend.get_ensembles().await } + async move { Ok(clone.handle.backend.cl().get_ensembles().await?) } })); this.selector.set_load_local(clone!(@weak this => move || { diff --git a/src/selectors/instrument.rs b/crates/musicus/src/selectors/instrument.rs similarity index 94% rename from src/selectors/instrument.rs rename to crates/musicus/src/selectors/instrument.rs index a8e8ddc..719d137 100644 --- a/src/selectors/instrument.rs +++ b/crates/musicus/src/selectors/instrument.rs @@ -1,5 +1,4 @@ use super::selector::Selector; -use crate::backend::{Backend, Instrument}; use crate::editors::InstrumentEditor; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; @@ -7,7 +6,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; -use std::cell::RefCell; +use musicus_backend::Instrument; use std::rc::Rc; /// A screen for selecting a instrument. @@ -45,7 +44,7 @@ impl Screen<(), Instrument> for InstrumentSelector { this.selector.set_load_online(clone!(@weak this => move || { let clone = this.clone(); - async move { clone.handle.backend.get_instruments().await } + async move { Ok(clone.handle.backend.cl().get_instruments().await?) } })); this.selector.set_load_local(clone!(@weak this => move || { diff --git a/src/selectors/mod.rs b/crates/musicus/src/selectors/mod.rs similarity index 100% rename from src/selectors/mod.rs rename to crates/musicus/src/selectors/mod.rs diff --git a/src/selectors/person.rs b/crates/musicus/src/selectors/person.rs similarity index 94% rename from src/selectors/person.rs rename to crates/musicus/src/selectors/person.rs index e8b7739..61514d3 100644 --- a/src/selectors/person.rs +++ b/crates/musicus/src/selectors/person.rs @@ -1,5 +1,4 @@ use super::selector::Selector; -use crate::backend::{Backend, Person}; use crate::editors::PersonEditor; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; @@ -7,7 +6,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; -use std::cell::RefCell; +use musicus_backend::Person; use std::rc::Rc; /// A screen for selecting a person. @@ -45,7 +44,7 @@ impl Screen<(), Person> for PersonSelector { this.selector.set_load_online(clone!(@weak this => move || { let clone = this.clone(); - async move { clone.handle.backend.get_persons().await } + async move { Ok(clone.handle.backend.cl().get_persons().await?) } })); this.selector.set_load_local(clone!(@weak this => move || { diff --git a/src/selectors/recording.rs b/crates/musicus/src/selectors/recording.rs similarity index 96% rename from src/selectors/recording.rs rename to crates/musicus/src/selectors/recording.rs index 95700be..5a27c91 100644 --- a/src/selectors/recording.rs +++ b/crates/musicus/src/selectors/recording.rs @@ -1,5 +1,4 @@ use super::selector::Selector; -use crate::backend::{Backend, Person, Work, Recording}; use crate::editors::{PersonEditor, WorkEditor, RecordingEditor}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; @@ -7,7 +6,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; -use std::cell::RefCell; +use musicus_backend::{Person, Work, Recording}; use std::rc::Rc; /// A screen for selecting a recording. @@ -56,7 +55,7 @@ impl Screen<(), Recording> for RecordingSelector { })); this.selector.set_load_online(clone!(@weak this => move || { - async move { this.handle.backend.get_persons().await } + async move { Ok(this.handle.backend.cl().get_persons().await?) } })); this.selector.set_load_local(clone!(@weak this => move || { @@ -134,7 +133,7 @@ impl Screen for RecordingSelectorWorkScreen { })); this.selector.set_load_online(clone!(@weak this => move || { - async move { this.handle.backend.get_works(&this.person.id).await } + async move { Ok(this.handle.backend.cl().get_works(&this.person.id).await?) } })); this.selector.set_load_local(clone!(@weak this => move || { @@ -199,7 +198,7 @@ impl Screen for RecordingSelectorRecordingScreen { })); this.selector.set_load_online(clone!(@weak this => move || { - async move { this.handle.backend.get_recordings_for_work(&this.work.id).await } + async move { Ok(this.handle.backend.cl().get_recordings_for_work(&this.work.id).await?) } })); this.selector.set_load_local(clone!(@weak this => move || { diff --git a/src/selectors/selector.rs b/crates/musicus/src/selectors/selector.rs similarity index 99% rename from src/selectors/selector.rs rename to crates/musicus/src/selectors/selector.rs index a7bea92..a191116 100644 --- a/src/selectors/selector.rs +++ b/crates/musicus/src/selectors/selector.rs @@ -1,8 +1,8 @@ -use crate::backend::Result; use crate::widgets::List; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; +use musicus_backend::Result; use std::cell::RefCell; use std::future::Future; use std::pin::Pin; diff --git a/src/selectors/work.rs b/crates/musicus/src/selectors/work.rs similarity index 95% rename from src/selectors/work.rs rename to crates/musicus/src/selectors/work.rs index f81e42d..17d1b9a 100644 --- a/src/selectors/work.rs +++ b/crates/musicus/src/selectors/work.rs @@ -1,5 +1,4 @@ use super::selector::Selector; -use crate::backend::{Backend, Person, Work}; use crate::editors::{PersonEditor, WorkEditor}; use crate::navigator::{NavigationHandle, Screen}; use crate::widgets::Widget; @@ -7,7 +6,7 @@ use gettextrs::gettext; use glib::clone; use gtk::prelude::*; use libadwaita::prelude::*; -use std::cell::RefCell; +use musicus_backend::{Person, Work}; use std::rc::Rc; /// A screen for selecting a work. @@ -50,7 +49,7 @@ impl Screen<(), Work> for WorkSelector { })); this.selector.set_load_online(clone!(@weak this => move || { - async move { this.handle.backend.get_persons().await } + async move { Ok(this.handle.backend.cl().get_persons().await?) } })); this.selector.set_load_local(clone!(@weak this => move || { @@ -124,7 +123,7 @@ impl Screen for WorkSelectorWorkScreen { })); this.selector.set_load_online(clone!(@weak this => move || { - async move { this.handle.backend.get_works(&this.person.id).await } + async move { Ok(this.handle.backend.cl().get_works(&this.person.id).await?) } })); this.selector.set_load_local(clone!(@weak this => move || { diff --git a/src/widgets/button_row.rs b/crates/musicus/src/widgets/button_row.rs similarity index 100% rename from src/widgets/button_row.rs rename to crates/musicus/src/widgets/button_row.rs diff --git a/src/widgets/editor.rs b/crates/musicus/src/widgets/editor.rs similarity index 99% rename from src/widgets/editor.rs rename to crates/musicus/src/widgets/editor.rs index 7af32ab..75f83fd 100644 --- a/src/widgets/editor.rs +++ b/crates/musicus/src/widgets/editor.rs @@ -1,5 +1,4 @@ use super::Widget; -use gio::prelude::*; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; diff --git a/src/widgets/entry_row.rs b/crates/musicus/src/widgets/entry_row.rs similarity index 100% rename from src/widgets/entry_row.rs rename to crates/musicus/src/widgets/entry_row.rs diff --git a/src/widgets/indexed_list_model.rs b/crates/musicus/src/widgets/indexed_list_model.rs similarity index 91% rename from src/widgets/indexed_list_model.rs rename to crates/musicus/src/widgets/indexed_list_model.rs index ec8cb93..6d8395d 100644 --- a/src/widgets/indexed_list_model.rs +++ b/crates/musicus/src/widgets/indexed_list_model.rs @@ -68,7 +68,7 @@ mod indexed_list_model { PROPERTIES.as_ref() } - fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + fn set_property(&self, _obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { match pspec.get_name() { "length" => { let length = value.get().unwrap().unwrap(); @@ -78,7 +78,7 @@ mod indexed_list_model { } } - fn get_property(&self, _obj: &Self::Type, id: usize, pspec: &glib::ParamSpec) -> glib::Value { + fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { match pspec.get_name() { "length" => self.length.get().to_value(), _ => unimplemented!(), @@ -160,7 +160,7 @@ mod item_index { PROPERTIES.as_ref() } - fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + fn set_property(&self, _obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { match pspec.get_name() { "value" => { let value = value.get().unwrap().unwrap(); @@ -170,7 +170,7 @@ mod item_index { } } - fn get_property(&self, _obj: &Self::Type, id: usize, pspec: &glib::ParamSpec) -> glib::Value { + fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { match pspec.get_name() { "value" => self.value.get().to_value(), _ => unimplemented!(), diff --git a/src/widgets/list.rs b/crates/musicus/src/widgets/list.rs similarity index 94% rename from src/widgets/list.rs rename to crates/musicus/src/widgets/list.rs index b757f3a..950b2e8 100644 --- a/src/widgets/list.rs +++ b/crates/musicus/src/widgets/list.rs @@ -119,14 +119,6 @@ impl List { self.widget.set_selection_mode(gtk::SelectionMode::Single); } - /// Select an item by its index. If the index is out of range, nothing will happen. - pub fn select(&self, index: usize) { - let row = self.widget.get_row_at_index(index as i32); - if let Some(row) = row { - self.widget.select_row(Some(&row)); - } - } - /// Refilter the list based on the filter callback. pub fn invalidate_filter(&self) { self.filter.changed(gtk::FilterChange::Different); diff --git a/src/widgets/mod.rs b/crates/musicus/src/widgets/mod.rs similarity index 100% rename from src/widgets/mod.rs rename to crates/musicus/src/widgets/mod.rs diff --git a/src/widgets/player_bar.rs b/crates/musicus/src/widgets/player_bar.rs similarity index 99% rename from src/widgets/player_bar.rs rename to crates/musicus/src/widgets/player_bar.rs index 387ea87..c2764ca 100644 --- a/src/widgets/player_bar.rs +++ b/crates/musicus/src/widgets/player_bar.rs @@ -1,7 +1,7 @@ -use crate::backend::{Player, PlaylistItem}; use glib::clone; use gtk::prelude::*; use gtk_macros::get_widget; +use musicus_backend::{Player, PlaylistItem}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/widgets/poe_list.rs b/crates/musicus/src/widgets/poe_list.rs similarity index 98% rename from src/widgets/poe_list.rs rename to crates/musicus/src/widgets/poe_list.rs index e5daa1a..a7a0e57 100644 --- a/src/widgets/poe_list.rs +++ b/crates/musicus/src/widgets/poe_list.rs @@ -1,9 +1,8 @@ use super::*; -use crate::backend::{Backend, Person, Ensemble}; use glib::clone; -use gtk::prelude::*; use gtk_macros::get_widget; use libadwaita::prelude::*; +use musicus_backend::{Backend, Person, Ensemble}; use std::cell::RefCell; use std::rc::Rc; diff --git a/src/widgets/screen.rs b/crates/musicus/src/widgets/screen.rs similarity index 100% rename from src/widgets/screen.rs rename to crates/musicus/src/widgets/screen.rs diff --git a/src/widgets/section.rs b/crates/musicus/src/widgets/section.rs similarity index 100% rename from src/widgets/section.rs rename to crates/musicus/src/widgets/section.rs diff --git a/src/widgets/upload_section.rs b/crates/musicus/src/widgets/upload_section.rs similarity index 92% rename from src/widgets/upload_section.rs rename to crates/musicus/src/widgets/upload_section.rs index 411b72b..90718fa 100644 --- a/src/widgets/upload_section.rs +++ b/crates/musicus/src/widgets/upload_section.rs @@ -1,7 +1,6 @@ use super::Section; use gettextrs::gettext; -use gtk::prelude::*; use libadwaita::prelude::*; /// A section showing a switch to enable uploading an item. @@ -9,9 +8,6 @@ pub struct UploadSection { /// The GTK widget of the wrapped section. pub widget: gtk::Box, - /// The section itself. - section: Section, - /// The upload switch. switch: gtk::Switch, } @@ -41,7 +37,6 @@ impl UploadSection { Self { widget: section.widget.clone(), - section, switch, } } diff --git a/src/window.rs b/crates/musicus/src/window.rs similarity index 97% rename from src/window.rs rename to crates/musicus/src/window.rs index 97a1eee..d5165e8 100644 --- a/src/window.rs +++ b/crates/musicus/src/window.rs @@ -1,4 +1,3 @@ -use crate::backend::*; use crate::config; use crate::import::SourceSelector; use crate::preferences::Preferences; @@ -11,6 +10,7 @@ use gio::prelude::*; use glib::clone; use gtk::prelude::*; use gtk_macros::{action, get_widget}; +use musicus_backend::{Backend, BackendState}; use std::rc::Rc; pub struct Window { @@ -202,12 +202,6 @@ impl Window { self.window.present(); } - fn reload(&self) { - self.poe_list.clone().reload(); - self.navigator.reset(); - self.leaflet.set_visible_child(&self.sidebar_box); - } - fn show_about_dialog(&self) { let dialog = gtk::AboutDialogBuilder::new() .transient_for(&self.window) diff --git a/crates/musicus_backend/Cargo.toml b/crates/musicus_backend/Cargo.toml new file mode 100644 index 0000000..fb14f99 --- /dev/null +++ b/crates/musicus_backend/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "musicus_backend" +version = "0.1.0" +edition = "2018" + +[dependencies] +fragile = "1.0.0" +futures-channel = "0.3.5" +gio = "0.9.1" +glib = "0.10.3" +gstreamer = "0.16.4" +gstreamer-player = "0.16.3" +musicus_client = { version = "0.1.0", path = "../musicus_client" } +musicus_database = { version = "0.1.0", path = "../musicus_database" } +secret-service = "2.0.1" +thiserror = "1.0.23" + diff --git a/crates/musicus_backend/src/error.rs b/crates/musicus_backend/src/error.rs new file mode 100644 index 0000000..522ac6c --- /dev/null +++ b/crates/musicus_backend/src/error.rs @@ -0,0 +1,28 @@ +/// An error that can happened within the backend. +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error(transparent)] + ClientError(#[from] musicus_client::Error), + + #[error(transparent)] + DatabaseError(#[from] musicus_database::Error), + + #[error("An error happened using the SecretService.")] + SecretServiceError(#[from] secret_service::Error), + + #[error("An error happened in GLib.")] + GlibError(#[from] glib::BoolError), + + #[error("A channel was canceled.")] + ChannelError(#[from] futures_channel::oneshot::Canceled), + + #[error("An error happened while decoding to UTF-8.")] + Utf8Error(#[from] std::str::Utf8Error), + + #[error("An error happened: {0}")] + Other(&'static str), +} + + +pub type Result = std::result::Result; + diff --git a/src/backend/mod.rs b/crates/musicus_backend/src/lib.rs similarity index 60% rename from src/backend/mod.rs rename to crates/musicus_backend/src/lib.rs index bbf2426..5b6995b 100644 --- a/src/backend/mod.rs +++ b/crates/musicus_backend/src/lib.rs @@ -1,17 +1,18 @@ use futures_channel::mpsc; +use gio::prelude::*; use std::cell::RefCell; use std::path::PathBuf; use std::rc::Rc; -pub mod client; -pub use client::*; - -pub mod database; -pub use database::*; +pub use musicus_client::*; +pub use musicus_database::*; pub mod error; pub use error::*; +// Override the identically named types from the other crates. +pub use error::{Error, Result}; + pub mod library; pub use library::*; @@ -43,9 +44,7 @@ pub struct Backend { music_library_path: RefCell>, database: RefCell>>, player: RefCell>>, - server_url: RefCell>, - login_data: RefCell>, - token: RefCell>, + client: Client, } impl Backend { @@ -61,20 +60,55 @@ impl Backend { music_library_path: RefCell::new(None), database: RefCell::new(None), player: RefCell::new(None), - server_url: RefCell::new(None), - login_data: RefCell::new(None), - token: RefCell::new(None), + client: Client::new(), } } /// Initialize the backend updating the state accordingly. pub async fn init(self: Rc) -> Result<()> { self.init_library().await?; - self.init_client()?; + + if let Some(url) = self.settings.get_string("server-url") { + if !url.is_empty() { + self.client.set_server_url(&url); + } + } + + if let Some(data) = secure::load_login_data()? { + self.client.set_login_data(data); + } Ok(()) } + /// Set the URL of the Musicus server to connect to. + pub fn set_server_url(&self, url: &str) -> Result<()> { + self.settings.set_string("server-url", url)?; + self.client.set_server_url(url); + Ok(()) + } + + /// Get the currently set server URL. + pub fn get_server_url(&self) -> Option { + self.client.get_server_url() + } + + /// Set the user credentials to use. + pub async fn set_login_data(&self, data: LoginData) -> Result<()> { + secure::store_login_data(data.clone()).await?; + self.client.set_login_data(data); + Ok(()) + } + + pub fn cl(&self) -> &Client { + &self.client + } + + /// Get the currently stored login credentials. + pub fn get_login_data(&self) -> Option { + self.client.get_login_data() + } + /// Set the current state and notify the user interface. fn set_state(&self, state: BackendState) { self.state_sender.borrow_mut().try_send(state).unwrap(); diff --git a/src/backend/library.rs b/crates/musicus_backend/src/library.rs similarity index 96% rename from src/backend/library.rs rename to crates/musicus_backend/src/library.rs index eef75e2..cad6b57 100644 --- a/src/backend/library.rs +++ b/crates/musicus_backend/src/library.rs @@ -1,4 +1,5 @@ -use crate::backend::{Backend, BackendState, DbThread, Player, Result}; +use crate::{Backend, BackendState, Player, Result}; +use musicus_database::DbThread; use gio::prelude::*; use std::path::PathBuf; use std::rc::Rc; diff --git a/src/backend/player.rs b/crates/musicus_backend/src/player.rs similarity index 99% rename from src/backend/player.rs rename to crates/musicus_backend/src/player.rs index 060c5e7..cdb0da0 100644 --- a/src/backend/player.rs +++ b/crates/musicus_backend/src/player.rs @@ -1,4 +1,5 @@ -use crate::backend::{Error, Result, TrackSet}; +use crate::{Error, Result}; +use musicus_database::TrackSet; use gstreamer_player::prelude::*; use std::cell::{Cell, RefCell}; use std::path::PathBuf; diff --git a/src/backend/secure.rs b/crates/musicus_backend/src/secure.rs similarity index 97% rename from src/backend/secure.rs rename to crates/musicus_backend/src/secure.rs index 5950651..702015f 100644 --- a/src/backend/secure.rs +++ b/crates/musicus_backend/src/secure.rs @@ -1,4 +1,5 @@ -use crate::backend::{LoginData, Result}; +use crate::Result; +use musicus_client::LoginData; use futures_channel::oneshot; use secret_service::{Collection, EncryptionType, SecretService}; use std::collections::HashMap; diff --git a/crates/musicus_client/Cargo.toml b/crates/musicus_client/Cargo.toml new file mode 100644 index 0000000..6cde9bd --- /dev/null +++ b/crates/musicus_client/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "musicus_client" +version = "0.1.0" +edition = "2018" + +[dependencies] +isahc = "0.9.12" +musicus_database = { version = "0.1.0", path = "../musicus_database" } +serde = { version = "1.0.117", features = ["derive"] } +serde_json = "1.0.59" +thiserror = "1.0.23" diff --git a/src/backend/client/ensembles.rs b/crates/musicus_client/src/ensembles.rs similarity index 86% rename from src/backend/client/ensembles.rs rename to crates/musicus_client/src/ensembles.rs index ed7cd3d..7068bd7 100644 --- a/src/backend/client/ensembles.rs +++ b/crates/musicus_client/src/ensembles.rs @@ -1,6 +1,7 @@ -use crate::backend::{Backend, Ensemble, Result}; +use crate::{Client, Result}; +use musicus_database::Ensemble; -impl Backend { +impl Client { /// Get all available ensembles from the server. pub async fn get_ensembles(&self) -> Result> { let body = self.get("ensembles").await?; diff --git a/src/backend/error.rs b/crates/musicus_client/src/error.rs similarity index 53% rename from src/backend/error.rs rename to crates/musicus_client/src/error.rs index 34e6aa0..c14f64d 100644 --- a/src/backend/error.rs +++ b/crates/musicus_client/src/error.rs @@ -1,6 +1,6 @@ use isahc::http::StatusCode; -/// An error that can happen within the backend. +/// An error within the client. #[derive(thiserror::Error, Debug)] pub enum Error { #[error("The users login credentials were wrong.")] @@ -21,33 +21,14 @@ pub enum Error { #[error("A networking error happened.")] HttpError(#[from] isahc::http::Error), - #[error(transparent)] - DatabaseError(#[from] crate::backend::DatabaseError), + #[error("An error happened when serializing/deserializing.")] + SerdeError(#[from] serde_json::Error), #[error("An IO error happened.")] IoError(#[from] std::io::Error), - #[error("An error happened using the SecretService.")] - SecretServiceError(#[from] secret_service::Error), - - #[error("An error happened while serializing or deserializing.")] - SerdeError(#[from] serde_json::Error), - - #[error("An error happened in GLib.")] - GlibError(#[from] glib::BoolError), - - #[error("A channel was canceled.")] - ChannelError(#[from] futures_channel::oneshot::Canceled), - - #[error("Error decoding to UTF8.")] - Utf8Error(#[from] std::str::Utf8Error), - #[error("An error happened: {0}")] Other(&'static str), - - // TODO: Remove this once anyhow has been dropped as a dependency. - #[error("An unkown error happened.")] - Unknown(#[from] anyhow::Error), } diff --git a/src/backend/client/instruments.rs b/crates/musicus_client/src/instruments.rs similarity index 86% rename from src/backend/client/instruments.rs rename to crates/musicus_client/src/instruments.rs index 0e2b3ce..6607b9d 100644 --- a/src/backend/client/instruments.rs +++ b/crates/musicus_client/src/instruments.rs @@ -1,6 +1,7 @@ -use crate::backend::{Backend, Instrument, Result}; +use crate::{Client, Result}; +use musicus_database::Instrument; -impl Backend { +impl Client { /// Get all available instruments from the server. pub async fn get_instruments(&self) -> Result> { let body = self.get("instruments").await?; diff --git a/src/backend/client/mod.rs b/crates/musicus_client/src/lib.rs similarity index 62% rename from src/backend/client/mod.rs rename to crates/musicus_client/src/lib.rs index f87e69b..c6b24b8 100644 --- a/src/backend/client/mod.rs +++ b/crates/musicus_client/src/lib.rs @@ -1,13 +1,15 @@ -use crate::backend::{Backend, Error, Result, secure}; -use gio::prelude::*; use isahc::http::StatusCode; use isahc::prelude::*; use serde::Serialize; use std::time::Duration; +use std::cell::RefCell; pub mod ensembles; pub use ensembles::*; +pub mod error; +pub use error::*; + pub mod instruments; pub use instruments::*; @@ -34,37 +36,26 @@ pub struct LoginData { pub password: String, } -impl Backend { - /// Initialize the client. - pub(super) fn init_client(&self) -> Result<()> { - if let Some(data) = secure::load_login_data()? { - self.login_data.replace(Some(data)); - } +/// A client for accessing the Wolfgang API. +pub struct Client { + server_url: RefCell>, + login_data: RefCell>, + token: RefCell>, +} - if let Some(url) = self.settings.get_string("server-url") { - if !url.is_empty() { - self.server_url.replace(Some(url.to_string())); - } +impl Client { + /// Create a new client. + pub fn new() -> Self { + Self { + server_url: RefCell::new(None), + login_data: RefCell::new(None), + token: RefCell::new(None), } - - Ok(()) } /// Set the URL of the Musicus server to connect to. - pub fn set_server_url(&self, url: &str) -> Result<()> { - self.settings.set_string("server-url", url)?; - self.server_url.replace(Some(url.to_string())); - Ok(()) - } - - /// Get the currently used login token. - pub fn get_token(&self) -> Option { - self.token.borrow().clone() - } - - /// Set the login token to use. This will be done automatically by the login method. - pub fn set_token(&self, token: &str) { - self.token.replace(Some(token.to_string())); + pub fn set_server_url(&self, url: &str) { + self.server_url.replace(Some(url.to_owned())); } /// Get the currently set server URL. @@ -72,9 +63,10 @@ impl Backend { self.server_url.borrow().clone() } - /// Require the server URL to be set. - fn server_url(&self) -> Result { - self.get_server_url().ok_or(Error::Other("The server URL is not available!")) + /// Set the user credentials to use. + pub fn set_login_data(&self, data: LoginData) { + self.login_data.replace(Some(data)); + self.token.replace(None); } /// Get the currently stored login credentials. @@ -82,18 +74,6 @@ impl Backend { self.login_data.borrow().clone() } - fn login_data(&self) -> Result { - self.get_login_data().ok_or(Error::Other("The login data is unset!")) - } - - /// Set the user credentials to use. - pub async fn set_login_data(&self, data: LoginData) -> Result<()> { - secure::store_login_data(data.clone()).await?; - self.login_data.replace(Some(data)); - self.token.replace(None); - Ok(()) - } - /// Try to login a user with the provided credentials and return, wether the login suceeded. pub async fn login(&self) -> Result { let server_url = self.server_url()?; @@ -109,7 +89,7 @@ impl Backend { let success = match response.status() { StatusCode::OK => { let token = response.text_async().await?; - self.set_token(&token); + self.token.replace(Some(token)); true } StatusCode::UNAUTHORIZED => false, @@ -136,30 +116,27 @@ impl Backend { /// Make an authenticated post request to the server. async fn post(&self, url: &str, body: String) -> Result { - let body = match self.get_token() { - Some(_) => { - let mut response = self.post_priv(url, body.clone()).await?; + let body = if self.token.borrow().is_some() { + let mut response = self.post_priv(url, body.clone()).await?; - // Try one more time (maybe the token was expired) - if response.status() == StatusCode::UNAUTHORIZED { - if self.login().await? { - response = self.post_priv(url, body).await?; - } else { - Err(Error::LoginFailed)?; - } - } - - response.text_async().await? - } - None => { - let mut response = if self.login().await? { - self.post_priv(url, body).await? + // Try one more time (maybe the token was expired) + if response.status() == StatusCode::UNAUTHORIZED { + if self.login().await? { + response = self.post_priv(url, body).await?; } else { - Err(Error::LoginFailed)? - }; - - response.text_async().await? + Err(Error::LoginFailed)?; + } } + + response.text_async().await? + } else { + let mut response = if self.login().await? { + self.post_priv(url, body).await? + } else { + Err(Error::LoginFailed)? + }; + + response.text_async().await? }; Ok(body) @@ -168,7 +145,7 @@ impl Backend { /// Post something to the server assuming there is a valid login token. async fn post_priv(&self, url: &str, body: String) -> Result> { let server_url = self.server_url()?; - let token = self.get_token().ok_or(Error::Other("No login token found!"))?; + let token = self.token()?; let response = Request::post(format!("{}/{}", server_url, url)) .timeout(Duration::from_secs(10)) @@ -180,4 +157,19 @@ impl Backend { Ok(response) } + + /// Require the server URL to be set. + fn server_url(&self) -> Result { + self.get_server_url().ok_or(Error::Other("The server URL is not available!")) + } + + /// Require the login data to be set. + fn login_data(&self) -> Result { + self.get_login_data().ok_or(Error::Other("The login data is unset!")) + } + + /// Require a login token to be set. + fn token(&self) -> Result { + self.token.borrow().clone().ok_or(Error::Other("No login token found!")) + } } diff --git a/src/backend/client/mediums.rs b/crates/musicus_client/src/mediums.rs similarity index 92% rename from src/backend/client/mediums.rs rename to crates/musicus_client/src/mediums.rs index f346e5c..ad55434 100644 --- a/src/backend/client/mediums.rs +++ b/crates/musicus_client/src/mediums.rs @@ -1,6 +1,7 @@ -use crate::backend::{Backend, Medium, Result}; +use crate::{Client, Result}; +use musicus_database::Medium; -impl Backend { +impl Client { /// Get all available mediums from the server, that contain the specified /// recording. pub async fn get_mediums_for_recording(&self, recording_id: &str) -> Result> { diff --git a/src/backend/client/persons.rs b/crates/musicus_client/src/persons.rs similarity index 86% rename from src/backend/client/persons.rs rename to crates/musicus_client/src/persons.rs index 86aa9bd..bc14350 100644 --- a/src/backend/client/persons.rs +++ b/crates/musicus_client/src/persons.rs @@ -1,6 +1,7 @@ -use crate::backend::{Backend, Person, Result}; +use crate::{Client, Result}; +use musicus_database::Person; -impl Backend { +impl Client { /// Get all available persons from the server. pub async fn get_persons(&self) -> Result> { let body = self.get("persons").await?; diff --git a/src/backend/client/recordings.rs b/crates/musicus_client/src/recordings.rs similarity index 87% rename from src/backend/client/recordings.rs rename to crates/musicus_client/src/recordings.rs index 6fb7a69..07862a9 100644 --- a/src/backend/client/recordings.rs +++ b/crates/musicus_client/src/recordings.rs @@ -1,6 +1,7 @@ -use crate::backend::{Backend, Recording, Result}; +use crate::{Client, Result}; +use musicus_database::Recording; -impl Backend { +impl Client { /// Get all available recordings from the server. pub async fn get_recordings_for_work(&self, work_id: &str) -> Result> { let body = self.get(&format!("works/{}/recordings", work_id)).await?; diff --git a/src/backend/client/register.rs b/crates/musicus_client/src/register.rs similarity index 91% rename from src/backend/client/register.rs rename to crates/musicus_client/src/register.rs index ee4b3b6..b48e282 100644 --- a/src/backend/client/register.rs +++ b/crates/musicus_client/src/register.rs @@ -1,4 +1,4 @@ -use crate::backend::{Backend, Result}; +use crate::{Client, Result}; use isahc::http::StatusCode; use isahc::prelude::*; use serde::{Deserialize, Serialize}; @@ -23,7 +23,7 @@ pub struct UserRegistration { pub answer: String, } -impl Backend { +impl Client { /// Request a new captcha for registration. pub async fn get_captcha(&self) -> Result { let body = self.get("captcha").await?; @@ -36,7 +36,7 @@ impl Backend { pub async fn register(&self, data: UserRegistration) -> Result { let server_url = self.server_url()?; - let mut response = Request::post(format!("{}/users", server_url)) + let response = Request::post(format!("{}/users", server_url)) .timeout(Duration::from_secs(10)) .header("Content-Type", "application/json") .body(serde_json::to_string(&data)?)? diff --git a/src/backend/client/works.rs b/crates/musicus_client/src/works.rs similarity index 87% rename from src/backend/client/works.rs rename to crates/musicus_client/src/works.rs index 5608f36..d4e5bcd 100644 --- a/src/backend/client/works.rs +++ b/crates/musicus_client/src/works.rs @@ -1,6 +1,7 @@ -use crate::backend::{Backend, Result, Work}; +use crate::{Client, Result}; +use musicus_database::Work; -impl Backend { +impl Client { /// Get all available works from the server. pub async fn get_works(&self, composer_id: &str) -> Result> { let body = self.get(&format!("persons/{}/works", composer_id)).await?; diff --git a/crates/musicus_database/Cargo.toml b/crates/musicus_database/Cargo.toml new file mode 100644 index 0000000..7a246a4 --- /dev/null +++ b/crates/musicus_database/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "musicus_database" +version = "0.1.0" +edition = "2018" +workspace = "../.." + +[dependencies] +diesel = { version = "1.4.5", features = ["sqlite"] } +diesel_migrations = "1.4.0" +futures-channel = "0.3.5" +rand = "0.7.3" +serde = { version = "1.0.117", features = ["derive"] } +serde_json = "1.0.59" +thiserror = "1.0.23" +uuid = { version = "0.8", features = ["v4"] } diff --git a/diesel.toml b/crates/musicus_database/diesel.toml similarity index 100% rename from diesel.toml rename to crates/musicus_database/diesel.toml diff --git a/src/backend/database/ensembles.rs b/crates/musicus_database/src/ensembles.rs similarity index 77% rename from src/backend/database/ensembles.rs rename to crates/musicus_database/src/ensembles.rs index 13dd6d1..5b9b01f 100644 --- a/src/backend/database/ensembles.rs +++ b/crates/musicus_database/src/ensembles.rs @@ -1,5 +1,5 @@ use super::schema::ensembles; -use super::{Database, DatabaseResult}; +use super::{Database, Result}; use diesel::prelude::*; use serde::{Deserialize, Serialize}; @@ -13,7 +13,7 @@ pub struct Ensemble { impl Database { /// Update an existing ensemble or insert a new one. - pub fn update_ensemble(&self, ensemble: Ensemble) -> DatabaseResult<()> { + pub fn update_ensemble(&self, ensemble: Ensemble) -> Result<()> { self.defer_foreign_keys()?; self.connection.transaction(|| { @@ -26,7 +26,7 @@ impl Database { } /// Get an existing ensemble. - pub fn get_ensemble(&self, id: &str) -> DatabaseResult> { + pub fn get_ensemble(&self, id: &str) -> Result> { let ensemble = ensembles::table .filter(ensembles::id.eq(id)) .load::(&self.connection)? @@ -37,14 +37,14 @@ impl Database { } /// Delete an existing ensemble. - pub fn delete_ensemble(&self, id: &str) -> DatabaseResult<()> { + pub fn delete_ensemble(&self, id: &str) -> Result<()> { diesel::delete(ensembles::table.filter(ensembles::id.eq(id))).execute(&self.connection)?; Ok(()) } /// Get all existing ensembles. - pub fn get_ensembles(&self) -> DatabaseResult> { + pub fn get_ensembles(&self) -> Result> { let ensembles = ensembles::table.load::(&self.connection)?; Ok(ensembles) diff --git a/src/backend/database/error.rs b/crates/musicus_database/src/error.rs similarity index 82% rename from src/backend/database/error.rs rename to crates/musicus_database/src/error.rs index ac8a739..c9c343f 100644 --- a/src/backend/database/error.rs +++ b/crates/musicus_database/src/error.rs @@ -1,8 +1,6 @@ -use thiserror::Error; - /// Error that happens within the database module. -#[derive(Error, Debug)] -pub enum DatabaseError { +#[derive(thiserror::Error, Debug)] +pub enum Error { #[error(transparent)] ConnectionError(#[from] diesel::result::ConnectionError), @@ -23,4 +21,4 @@ pub enum DatabaseError { } /// Return type for database methods. -pub type DatabaseResult = Result; +pub type Result = std::result::Result; diff --git a/src/backend/database/instruments.rs b/crates/musicus_database/src/instruments.rs similarity index 78% rename from src/backend/database/instruments.rs rename to crates/musicus_database/src/instruments.rs index 0848b00..107eee6 100644 --- a/src/backend/database/instruments.rs +++ b/crates/musicus_database/src/instruments.rs @@ -1,5 +1,5 @@ use super::schema::instruments; -use super::{Database, DatabaseResult}; +use super::{Database, Result}; use diesel::prelude::*; use serde::{Deserialize, Serialize}; @@ -13,7 +13,7 @@ pub struct Instrument { impl Database { /// Update an existing instrument or insert a new one. - pub fn update_instrument(&self, instrument: Instrument) -> DatabaseResult<()> { + pub fn update_instrument(&self, instrument: Instrument) -> Result<()> { self.defer_foreign_keys()?; self.connection.transaction(|| { @@ -26,7 +26,7 @@ impl Database { } /// Get an existing instrument. - pub fn get_instrument(&self, id: &str) -> DatabaseResult> { + pub fn get_instrument(&self, id: &str) -> Result> { let instrument = instruments::table .filter(instruments::id.eq(id)) .load::(&self.connection)? @@ -37,7 +37,7 @@ impl Database { } /// Delete an existing instrument. - pub fn delete_instrument(&self, id: &str) -> DatabaseResult<()> { + pub fn delete_instrument(&self, id: &str) -> Result<()> { diesel::delete(instruments::table.filter(instruments::id.eq(id))) .execute(&self.connection)?; @@ -45,7 +45,7 @@ impl Database { } /// Get all existing instruments. - pub fn get_instruments(&self) -> DatabaseResult> { + pub fn get_instruments(&self) -> Result> { let instruments = instruments::table.load::(&self.connection)?; Ok(instruments) diff --git a/src/backend/database/mod.rs b/crates/musicus_database/src/lib.rs similarity index 82% rename from src/backend/database/mod.rs rename to crates/musicus_database/src/lib.rs index c0f8bbd..61f8b44 100644 --- a/src/backend/database/mod.rs +++ b/crates/musicus_database/src/lib.rs @@ -1,3 +1,11 @@ +// Required for schema.rs +#[macro_use] +extern crate diesel; + +// Required for embed_migrations macro in database.rs +#[macro_use] +extern crate diesel_migrations; + use diesel::prelude::*; pub mod ensembles; @@ -44,7 +52,7 @@ pub struct Database { impl Database { /// Create a new database interface and run migrations if necessary. - pub fn new(file_name: &str) -> DatabaseResult { + pub fn new(file_name: &str) -> Result { let connection = SqliteConnection::establish(file_name)?; diesel::sql_query("PRAGMA foreign_keys = ON").execute(&connection)?; @@ -54,7 +62,7 @@ impl Database { } /// Defer all foreign keys for the next transaction. - fn defer_foreign_keys(&self) -> DatabaseResult<()> { + fn defer_foreign_keys(&self) -> Result<()> { diesel::sql_query("PRAGMA defer_foreign_keys = ON").execute(&self.connection)?; Ok(()) } diff --git a/src/backend/database/medium.rs b/crates/musicus_database/src/medium.rs similarity index 89% rename from src/backend/database/medium.rs rename to crates/musicus_database/src/medium.rs index b0626c8..3f42878 100644 --- a/src/backend/database/medium.rs +++ b/crates/musicus_database/src/medium.rs @@ -1,6 +1,6 @@ use super::generate_id; use super::schema::{mediums, recordings, track_sets, tracks}; -use super::{Database, DatabaseError, Recording, DatabaseResult}; +use super::{Database, Error, Recording, Result}; use diesel::prelude::*; use serde::{Deserialize, Serialize}; @@ -79,10 +79,10 @@ struct TrackRow { impl Database { /// Update an existing medium or insert a new one. - pub fn update_medium(&self, medium: Medium) -> DatabaseResult<()> { + pub fn update_medium(&self, medium: Medium) -> Result<()> { self.defer_foreign_keys()?; - self.connection.transaction::<(), DatabaseError, _>(|| { + self.connection.transaction::<(), Error, _>(|| { let medium_id = &medium.id; // This will also delete the track sets and tracks. @@ -152,7 +152,7 @@ impl Database { } /// Get an existing medium. - pub fn get_medium(&self, id: &str) -> DatabaseResult> { + pub fn get_medium(&self, id: &str) -> Result> { let row = mediums::table .filter(mediums::id.eq(id)) .load::(&self.connection)? @@ -169,13 +169,13 @@ impl Database { /// Delete a medium and all of its tracks. This will fail, if the music /// library contains audio files referencing any of those tracks. - pub fn delete_medium(&self, id: &str) -> DatabaseResult<()> { + pub fn delete_medium(&self, id: &str) -> Result<()> { diesel::delete(mediums::table.filter(mediums::id.eq(id))).execute(&self.connection)?; Ok(()) } /// Get all available track sets for a recording. - pub fn get_track_sets(&self, recording_id: &str) -> DatabaseResult> { + pub fn get_track_sets(&self, recording_id: &str) -> Result> { let mut track_sets: Vec = Vec::new(); let rows = track_sets::table @@ -193,7 +193,7 @@ impl Database { } /// Retrieve all available information on a medium from related tables. - fn get_medium_data(&self, row: MediumRow) -> DatabaseResult { + fn get_medium_data(&self, row: MediumRow) -> Result { let track_set_rows = track_sets::table .filter(track_sets::medium.eq(&row.id)) .order_by(track_sets::index) @@ -217,12 +217,12 @@ impl Database { } /// Convert a track set row from the database to an actual track set. - fn get_track_set_from_row(&self, row: TrackSetRow) -> DatabaseResult { + fn get_track_set_from_row(&self, row: TrackSetRow) -> Result { let recording_id = row.recording; let recording = self .get_recording(&recording_id)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get recording ({}) for track set ({}).", recording_id, row.id, @@ -241,12 +241,11 @@ impl Database { .split(',') .map(|part_index| { str::parse(part_index) - .or(Err(DatabaseError::Other(format!( - "Failed to parse part index from '{}'.", - track_row.work_parts, - )))?) + .or(Err(Error::Other( + format!("Failed to parse part index from '{}'.", track_row.work_parts, + )))) }) - .collect::>>()?; + .collect::>>()?; let track = Track { work_parts, diff --git a/src/backend/database/persons.rs b/crates/musicus_database/src/persons.rs similarity index 82% rename from src/backend/database/persons.rs rename to crates/musicus_database/src/persons.rs index 64efe66..f47ea3d 100644 --- a/src/backend/database/persons.rs +++ b/crates/musicus_database/src/persons.rs @@ -1,5 +1,5 @@ use super::schema::persons; -use super::{Database, DatabaseResult}; +use super::{Database, Result}; use diesel::prelude::*; use serde::{Deserialize, Serialize}; @@ -26,7 +26,7 @@ impl Person { impl Database { /// Update an existing person or insert a new one. - pub fn update_person(&self, person: Person) -> DatabaseResult<()> { + pub fn update_person(&self, person: Person) -> Result<()> { self.defer_foreign_keys()?; self.connection.transaction(|| { @@ -39,7 +39,7 @@ impl Database { } /// Get an existing person. - pub fn get_person(&self, id: &str) -> DatabaseResult> { + pub fn get_person(&self, id: &str) -> Result> { let person = persons::table .filter(persons::id.eq(id)) .load::(&self.connection)? @@ -50,14 +50,14 @@ impl Database { } /// Delete an existing person. - pub fn delete_person(&self, id: &str) -> DatabaseResult<()> { + pub fn delete_person(&self, id: &str) -> Result<()> { diesel::delete(persons::table.filter(persons::id.eq(id))).execute(&self.connection)?; Ok(()) } /// Get all existing persons. - pub fn get_persons(&self) -> DatabaseResult> { + pub fn get_persons(&self) -> Result> { let persons = persons::table.load::(&self.connection)?; Ok(persons) diff --git a/src/backend/database/recordings.rs b/crates/musicus_database/src/recordings.rs similarity index 91% rename from src/backend/database/recordings.rs rename to crates/musicus_database/src/recordings.rs index ffe3dae..0fefbe6 100644 --- a/src/backend/database/recordings.rs +++ b/crates/musicus_database/src/recordings.rs @@ -1,6 +1,6 @@ use super::generate_id; use super::schema::{ensembles, performances, persons, recordings}; -use super::{Database, Ensemble, DatabaseError, Instrument, Person, DatabaseResult, Work}; +use super::{Database, Ensemble, Error, Instrument, Person, Result, Work}; use diesel::prelude::*; use serde::{Deserialize, Serialize}; @@ -119,9 +119,9 @@ impl Recording { impl Database { /// Update an existing recording or insert a new one. // TODO: Think about whether to also insert the other items. - pub fn update_recording(&self, recording: Recording) -> DatabaseResult<()> { + pub fn update_recording(&self, recording: Recording) -> Result<()> { self.defer_foreign_keys()?; - self.connection.transaction::<(), DatabaseError, _>(|| { + self.connection.transaction::<(), Error, _>(|| { let recording_id = &recording.id; self.delete_recording(recording_id)?; @@ -179,7 +179,7 @@ impl Database { } /// Check whether the database contains a recording. - pub fn recording_exists(&self, id: &str) -> DatabaseResult { + pub fn recording_exists(&self, id: &str) -> Result { let exists = recordings::table .filter(recordings::id.eq(id)) .load::(&self.connection)? @@ -190,7 +190,7 @@ impl Database { } /// Get an existing recording. - pub fn get_recording(&self, id: &str) -> DatabaseResult> { + pub fn get_recording(&self, id: &str) -> Result> { let row = recordings::table .filter(recordings::id.eq(id)) .load::(&self.connection)? @@ -206,7 +206,7 @@ impl Database { } /// Retrieve all available information on a recording from related tables. - fn get_recording_data(&self, row: RecordingRow) -> DatabaseResult { + fn get_recording_data(&self, row: RecordingRow) -> Result { let mut performance_descriptions: Vec = Vec::new(); let performance_rows = performances::table @@ -218,7 +218,7 @@ impl Database { person: match row.person { Some(id) => Some( self.get_person(&id)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get person ({}) for recording ({}).", id, row.id, @@ -229,7 +229,7 @@ impl Database { ensemble: match row.ensemble { Some(id) => Some( self.get_ensemble(&id)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get ensemble ({}) for recording ({}).", id, row.id, @@ -240,7 +240,7 @@ impl Database { role: match row.role { Some(id) => Some( self.get_instrument(&id)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get instrument ({}) for recording ({}).", id, row.id, @@ -254,7 +254,7 @@ impl Database { let work_id = &row.work; let work = self .get_work(work_id)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get work ({}) for recording ({}).", work_id, row.id, @@ -271,7 +271,7 @@ impl Database { } /// Get all available information on all recordings where a person is performing. - pub fn get_recordings_for_person(&self, person_id: &str) -> DatabaseResult> { + pub fn get_recordings_for_person(&self, person_id: &str) -> Result> { let mut recordings: Vec = Vec::new(); let rows = recordings::table @@ -289,7 +289,7 @@ impl Database { } /// Get all available information on all recordings where an ensemble is performing. - pub fn get_recordings_for_ensemble(&self, ensemble_id: &str) -> DatabaseResult> { + pub fn get_recordings_for_ensemble(&self, ensemble_id: &str) -> Result> { let mut recordings: Vec = Vec::new(); let rows = recordings::table @@ -307,7 +307,7 @@ impl Database { } /// Get allavailable information on all recordings of a work. - pub fn get_recordings_for_work(&self, work_id: &str) -> DatabaseResult> { + pub fn get_recordings_for_work(&self, work_id: &str) -> Result> { let mut recordings: Vec = Vec::new(); let rows = recordings::table @@ -323,7 +323,7 @@ impl Database { /// Delete an existing recording. This will fail if there are still references to this /// recording from other tables that are not directly part of the recording data. - pub fn delete_recording(&self, id: &str) -> DatabaseResult<()> { + pub fn delete_recording(&self, id: &str) -> Result<()> { diesel::delete(recordings::table.filter(recordings::id.eq(id))) .execute(&self.connection)?; Ok(()) diff --git a/src/backend/database/schema.rs b/crates/musicus_database/src/schema.rs similarity index 100% rename from src/backend/database/schema.rs rename to crates/musicus_database/src/schema.rs diff --git a/src/backend/database/thread.rs b/crates/musicus_database/src/thread.rs similarity index 76% rename from src/backend/database/thread.rs rename to crates/musicus_database/src/thread.rs index 87f9772..7a73a14 100644 --- a/src/backend/database/thread.rs +++ b/crates/musicus_database/src/thread.rs @@ -6,31 +6,31 @@ use std::thread; /// An action the database thread can perform. pub enum Action { - UpdatePerson(Person, Sender>), - GetPerson(String, Sender>>), - DeletePerson(String, Sender>), - GetPersons(Sender>>), - UpdateInstrument(Instrument, Sender>), - GetInstrument(String, Sender>>), - DeleteInstrument(String, Sender>), - GetInstruments(Sender>>), - UpdateWork(Work, Sender>), - DeleteWork(String, Sender>), - GetWorks(String, Sender>>), - UpdateEnsemble(Ensemble, Sender>), - GetEnsemble(String, Sender>>), - DeleteEnsemble(String, Sender>), - GetEnsembles(Sender>>), - UpdateRecording(Recording, Sender>), - DeleteRecording(String, Sender>), - GetRecordingsForPerson(String, Sender>>), - GetRecordingsForEnsemble(String, Sender>>), - GetRecordingsForWork(String, Sender>>), - RecordingExists(String, Sender>), - UpdateMedium(Medium, Sender>), - GetMedium(String, Sender>>), - DeleteMedium(String, Sender>), - GetTrackSets(String, Sender>>), + UpdatePerson(Person, Sender>), + GetPerson(String, Sender>>), + DeletePerson(String, Sender>), + GetPersons(Sender>>), + UpdateInstrument(Instrument, Sender>), + GetInstrument(String, Sender>>), + DeleteInstrument(String, Sender>), + GetInstruments(Sender>>), + UpdateWork(Work, Sender>), + DeleteWork(String, Sender>), + GetWorks(String, Sender>>), + UpdateEnsemble(Ensemble, Sender>), + GetEnsemble(String, Sender>>), + DeleteEnsemble(String, Sender>), + GetEnsembles(Sender>>), + UpdateRecording(Recording, Sender>), + DeleteRecording(String, Sender>), + GetRecordingsForPerson(String, Sender>>), + GetRecordingsForEnsemble(String, Sender>>), + GetRecordingsForWork(String, Sender>>), + RecordingExists(String, Sender>), + UpdateMedium(Medium, Sender>), + GetMedium(String, Sender>>), + DeleteMedium(String, Sender>), + GetTrackSets(String, Sender>>), Stop(Sender<()>), } @@ -43,7 +43,7 @@ pub struct DbThread { impl DbThread { /// Create a new database connection in a background thread. - pub async fn new(path: String) -> DatabaseResult { + pub async fn new(path: String) -> Result { let (action_sender, action_receiver) = mpsc::channel(); let (ready_sender, ready_receiver) = oneshot::channel(); @@ -149,14 +149,14 @@ impl DbThread { } /// Update an existing person or insert a new one. - pub async fn update_person(&self, person: Person) -> DatabaseResult<()> { + pub async fn update_person(&self, person: Person) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(UpdatePerson(person, sender))?; receiver.await? } /// Get an existing person. - pub async fn get_person(&self, id: &str) -> DatabaseResult> { + pub async fn get_person(&self, id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(GetPerson(id.to_string(), sender))?; receiver.await? @@ -164,7 +164,7 @@ impl DbThread { /// Delete an existing person. This will fail, if there are still other items referencing /// this person. - pub async fn delete_person(&self, id: &str) -> DatabaseResult<()> { + pub async fn delete_person(&self, id: &str) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(DeletePerson(id.to_string(), sender))?; @@ -172,14 +172,14 @@ impl DbThread { } /// Get all existing persons. - pub async fn get_persons(&self) -> DatabaseResult> { + pub async fn get_persons(&self) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(GetPersons(sender))?; receiver.await? } /// Update an existing instrument or insert a new one. - pub async fn update_instrument(&self, instrument: Instrument) -> DatabaseResult<()> { + pub async fn update_instrument(&self, instrument: Instrument) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(UpdateInstrument(instrument, sender))?; @@ -187,7 +187,7 @@ impl DbThread { } /// Get an existing instrument. - pub async fn get_instrument(&self, id: &str) -> DatabaseResult> { + pub async fn get_instrument(&self, id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(GetInstrument(id.to_string(), sender))?; @@ -196,7 +196,7 @@ impl DbThread { /// Delete an existing instrument. This will fail, if there are still other items referencing /// this instrument. - pub async fn delete_instrument(&self, id: &str) -> DatabaseResult<()> { + pub async fn delete_instrument(&self, id: &str) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(DeleteInstrument(id.to_string(), sender))?; @@ -204,14 +204,14 @@ impl DbThread { } /// Get all existing instruments. - pub async fn get_instruments(&self) -> DatabaseResult> { + pub async fn get_instruments(&self) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(GetInstruments(sender))?; receiver.await? } /// Update an existing work or insert a new one. - pub async fn update_work(&self, work: Work) -> DatabaseResult<()> { + pub async fn update_work(&self, work: Work) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(UpdateWork(work, sender))?; receiver.await? @@ -219,7 +219,7 @@ impl DbThread { /// Delete an existing work. This will fail, if there are still other items referencing /// this work. - pub async fn delete_work(&self, id: &str) -> DatabaseResult<()> { + pub async fn delete_work(&self, id: &str) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(DeleteWork(id.to_string(), sender))?; @@ -227,7 +227,7 @@ impl DbThread { } /// Get information on all existing works by a composer. - pub async fn get_works(&self, person_id: &str) -> DatabaseResult> { + pub async fn get_works(&self, person_id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(GetWorks(person_id.to_string(), sender))?; @@ -235,14 +235,14 @@ impl DbThread { } /// Update an existing ensemble or insert a new one. - pub async fn update_ensemble(&self, ensemble: Ensemble) -> DatabaseResult<()> { + pub async fn update_ensemble(&self, ensemble: Ensemble) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(UpdateEnsemble(ensemble, sender))?; receiver.await? } /// Get an existing ensemble. - pub async fn get_ensemble(&self, id: &str) -> DatabaseResult> { + pub async fn get_ensemble(&self, id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(GetEnsemble(id.to_string(), sender))?; @@ -251,7 +251,7 @@ impl DbThread { /// Delete an existing ensemble. This will fail, if there are still other items referencing /// this ensemble. - pub async fn delete_ensemble(&self, id: &str) -> DatabaseResult<()> { + pub async fn delete_ensemble(&self, id: &str) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(DeleteEnsemble(id.to_string(), sender))?; @@ -259,14 +259,14 @@ impl DbThread { } /// Get all existing ensembles. - pub async fn get_ensembles(&self) -> DatabaseResult> { + pub async fn get_ensembles(&self) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(GetEnsembles(sender))?; receiver.await? } /// Update an existing recording or insert a new one. - pub async fn update_recording(&self, recording: Recording) -> DatabaseResult<()> { + pub async fn update_recording(&self, recording: Recording) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(UpdateRecording(recording, sender))?; @@ -274,7 +274,7 @@ impl DbThread { } /// Delete an existing recording. - pub async fn delete_recording(&self, id: &str) -> DatabaseResult<()> { + pub async fn delete_recording(&self, id: &str) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(DeleteRecording(id.to_string(), sender))?; @@ -282,7 +282,7 @@ impl DbThread { } /// Get information on all recordings in which a person performs. - pub async fn get_recordings_for_person(&self, person_id: &str) -> DatabaseResult> { + pub async fn get_recordings_for_person(&self, person_id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(GetRecordingsForPerson(person_id.to_string(), sender))?; @@ -290,7 +290,7 @@ impl DbThread { } /// Get information on all recordings in which an ensemble performs. - pub async fn get_recordings_for_ensemble(&self, ensemble_id: &str) -> DatabaseResult> { + pub async fn get_recordings_for_ensemble(&self, ensemble_id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(GetRecordingsForEnsemble(ensemble_id.to_string(), sender))?; @@ -298,7 +298,7 @@ impl DbThread { } /// Get information on all recordings of a work. - pub async fn get_recordings_for_work(&self, work_id: &str) -> DatabaseResult> { + pub async fn get_recordings_for_work(&self, work_id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender .send(GetRecordingsForWork(work_id.to_string(), sender))?; @@ -306,7 +306,7 @@ impl DbThread { } /// Check whether a recording exists within the database. - pub async fn recording_exists(&self, id: &str) -> DatabaseResult { + pub async fn recording_exists(&self, id: &str) -> Result { let (sender, receiver) = oneshot::channel(); self.action_sender .send(RecordingExists(id.to_string(), sender))?; @@ -314,7 +314,7 @@ impl DbThread { } /// Update an existing medium or insert a new one. - pub async fn update_medium(&self, medium: Medium) -> DatabaseResult<()> { + pub async fn update_medium(&self, medium: Medium) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(UpdateMedium(medium, sender))?; receiver.await? @@ -322,7 +322,7 @@ impl DbThread { /// Delete an existing medium. This will fail, if there are still other /// items referencing this medium. - pub async fn delete_medium(&self, id: &str) -> DatabaseResult<()> { + pub async fn delete_medium(&self, id: &str) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender @@ -332,21 +332,21 @@ impl DbThread { } /// Get an existing medium. - pub async fn get_medium(&self, id: &str) -> DatabaseResult> { + pub async fn get_medium(&self, id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(GetMedium(id.to_owned(), sender))?; receiver.await? } /// Get all track sets for a recording. - pub async fn get_track_sets(&self, recording_id: &str) -> DatabaseResult> { + pub async fn get_track_sets(&self, recording_id: &str) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(GetTrackSets(recording_id.to_owned(), sender))?; receiver.await? } /// Stop the database thread. Any future access to the database will fail. - pub async fn stop(&self) -> DatabaseResult<()> { + pub async fn stop(&self) -> Result<()> { let (sender, receiver) = oneshot::channel(); self.action_sender.send(Stop(sender))?; Ok(receiver.await?) diff --git a/src/backend/database/works.rs b/crates/musicus_database/src/works.rs similarity index 92% rename from src/backend/database/works.rs rename to crates/musicus_database/src/works.rs index 418d8f1..e7e9ca3 100644 --- a/src/backend/database/works.rs +++ b/crates/musicus_database/src/works.rs @@ -1,10 +1,9 @@ use super::generate_id; use super::schema::{instrumentations, work_parts, work_sections, works}; -use super::{Database, DatabaseError, Instrument, Person, DatabaseResult}; +use super::{Database, Error, Instrument, Person, Result}; use diesel::prelude::*; use diesel::{Insertable, Queryable}; use serde::{Deserialize, Serialize}; -use std::convert::TryInto; /// Table row data for a work. #[derive(Insertable, Queryable, Debug, Clone)] @@ -105,10 +104,10 @@ impl Work { impl Database { /// Update an existing work or insert a new one. // TODO: Think about also inserting related items. - pub fn update_work(&self, work: Work) -> DatabaseResult<()> { + pub fn update_work(&self, work: Work) -> Result<()> { self.defer_foreign_keys()?; - self.connection.transaction::<(), DatabaseError, _>(|| { + self.connection.transaction::<(), Error, _>(|| { let work_id = &work.id; self.delete_work(work_id)?; @@ -194,7 +193,7 @@ impl Database { } /// Get an existing work. - pub fn get_work(&self, id: &str) -> DatabaseResult> { + pub fn get_work(&self, id: &str) -> Result> { let row = works::table .filter(works::id.eq(id)) .load::(&self.connection)? @@ -210,7 +209,7 @@ impl Database { } /// Retrieve all available information on a work from related tables. - fn get_work_data(&self, row: WorkRow) -> DatabaseResult { + fn get_work_data(&self, row: WorkRow) -> Result { let mut instruments: Vec = Vec::new(); let instrumentations = instrumentations::table @@ -221,7 +220,7 @@ impl Database { let id = &instrumentation.instrument; instruments.push( self.get_instrument(id)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get instrument ({}) for work ({}).", id, row.id, @@ -241,7 +240,7 @@ impl Database { composer: match part_row.composer { Some(composer) => Some( self.get_person(&composer)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get person ({}) for work ({}).", composer, row.id, @@ -268,7 +267,7 @@ impl Database { let person_id = &row.composer; let person = self .get_person(person_id)? - .ok_or(DatabaseError::Other(format!( + .ok_or(Error::Other(format!( "Failed to get person ({}) for work ({}).", person_id, row.id, @@ -286,13 +285,13 @@ impl Database { /// Delete an existing work. This will fail if there are still other tables that relate to /// this work except for the things that are part of the information on the work it - pub fn delete_work(&self, id: &str) -> DatabaseResult<()> { + pub fn delete_work(&self, id: &str) -> Result<()> { diesel::delete(works::table.filter(works::id.eq(id))).execute(&self.connection)?; Ok(()) } /// Get all existing works by a composer and related information from other tables. - pub fn get_works(&self, composer_id: &str) -> DatabaseResult> { + pub fn get_works(&self, composer_id: &str) -> Result> { let mut works: Vec = Vec::new(); let rows = works::table diff --git a/meson.build b/meson.build index 9f5f0a1..6e4b6d0 100644 --- a/meson.build +++ b/meson.build @@ -20,6 +20,6 @@ i18n = import('i18n') subdir('data') subdir('po') subdir('res') -subdir('src') +subdir('crates/musicus/src') meson.add_install_script('build-aux/postinstall.py') diff --git a/src/meson.build b/src/meson.build deleted file mode 100644 index 9e3d571..0000000 --- a/src/meson.build +++ /dev/null @@ -1,134 +0,0 @@ -prefix = get_option('prefix') -localedir = join_paths(prefix, get_option('localedir')) - -global_conf = configuration_data() -global_conf.set_quoted('LOCALEDIR', localedir) -global_conf.set_quoted('VERSION', meson.project_version()) -config_rs = configure_file( - input: 'config.rs.in', - output: 'config.rs', - configuration: global_conf -) - -run_command( - 'cp', - config_rs, - meson.current_source_dir(), - check: true -) - -resource_conf = configuration_data() -resource_conf.set_quoted('RESOURCEFILE', resources.full_path()) -resource_rs = configure_file( - input: 'resources.rs.in', - output: 'resources.rs', - configuration: resource_conf -) - -run_command( - 'cp', - resource_rs, - meson.current_source_dir(), - check: true -) - -sources = files( - 'backend/client/ensembles.rs', - 'backend/client/instruments.rs', - 'backend/client/mediums.rs', - 'backend/client/mod.rs', - 'backend/client/persons.rs', - 'backend/client/recordings.rs', - 'backend/client/register.rs', - 'backend/client/works.rs', - 'backend/database/ensembles.rs', - 'backend/database/error.rs', - 'backend/database/instruments.rs', - 'backend/database/medium.rs', - 'backend/database/mod.rs', - 'backend/database/persons.rs', - 'backend/database/recordings.rs', - 'backend/database/schema.rs', - 'backend/database/thread.rs', - 'backend/database/works.rs', - 'backend/error.rs', - 'backend/library.rs', - 'backend/mod.rs', - 'backend/player.rs', - 'backend/secure.rs', - 'editors/ensemble.rs', - 'editors/instrument.rs', - 'editors/mod.rs', - 'editors/performance.rs', - 'editors/person.rs', - 'editors/recording.rs', - 'editors/work.rs', - 'editors/work_part.rs', - 'editors/work_section.rs', - 'import/disc_source.rs', - 'import/folder_source.rs', - 'import/medium_editor.rs', - 'import/mod.rs', - 'import/source.rs', - 'import/source_selector.rs', - 'import/track_editor.rs', - 'import/track_selector.rs', - 'import/track_set_editor.rs', - 'navigator/mod.rs', - 'navigator/window.rs', - 'preferences/login.rs', - 'preferences/mod.rs', - 'preferences/register.rs', - 'preferences/server.rs', - 'screens/ensemble.rs', - 'screens/mod.rs', - 'screens/person.rs', - 'screens/player_screen.rs', - 'screens/recording.rs', - 'screens/work.rs', - 'selectors/ensemble.rs', - 'selectors/instrument.rs', - 'selectors/mod.rs', - 'selectors/person.rs', - 'selectors/recording.rs', - 'selectors/selector.rs', - 'selectors/work.rs', - 'widgets/button_row.rs', - 'widgets/editor.rs', - 'widgets/entry_row.rs', - 'widgets/upload_section.rs', - 'widgets/indexed_list_model.rs', - 'widgets/list.rs', - 'widgets/mod.rs', - 'widgets/player_bar.rs', - 'widgets/poe_list.rs', - 'widgets/screen.rs', - 'widgets/section.rs', - 'config.rs', - 'config.rs.in', - 'macros.rs', - 'main.rs', - 'resources.rs', - 'resources.rs.in', - 'window.rs', -) - -cargo_script = find_program(join_paths(meson.source_root(), 'build-aux/cargo.sh')) -cargo_release = custom_target( - 'cargo-build', - build_by_default: true, - input: sources, - depends: resources, - output: meson.project_name(), - console: true, - install: true, - install_dir: get_option('bindir'), - command: [ - cargo_script, - meson.build_root(), - meson.source_root(), - '@OUTPUT@', - get_option('buildtype'), - meson.project_name(), - ] -)