Compare commits
6 commits
master
...
load-billi
Author | SHA1 | Date | |
---|---|---|---|
92a22100be | |||
f8870594ce | |||
8410f27738 | |||
f22ce33a35 | |||
44a3362679 | |||
0ffda24b2a |
20 changed files with 655 additions and 121 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,3 +9,4 @@ devenv.local.nix
|
|||
|
||||
# pre-commit
|
||||
.pre-commit-config.yaml
|
||||
rustc-ice-*.txt
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
thread 'rustc' panicked at compiler/rustc_middle/src/query/on_disk_cache.rs:736:21:
|
||||
Failed to convert DefPathHash DefPathHash(Fingerprint(9597590199268592635, 17791879502897349522))
|
||||
stack backtrace:
|
||||
0: 0x7fbfbb48d025 - std::backtrace::Backtrace::create::hbc256ff4bc983c0b
|
||||
1: 0x7fbfb9c8c865 - std::backtrace::Backtrace::force_capture::h1ebb6042c5b424a8
|
||||
2: 0x7fbfb8db2217 - std[11ac8361619e45fd]::panicking::update_hook::<alloc[1ed43557cf619c2]::boxed::Box<rustc_driver_impl[8c32a9dec5e4d0f0]::install_ice_hook::{closure#0}>>::{closure#0}
|
||||
3: 0x7fbfb9ca3ee8 - std::panicking::rust_panic_with_hook::ha6cfc51100acb1ab
|
||||
4: 0x7fbfb9ca3cb7 - std::panicking::begin_panic_handler::{{closure}}::he56e1efe5ba67ce1
|
||||
5: 0x7fbfb9ca1699 - std::sys::backtrace::__rust_end_short_backtrace::hcc7bf1345a5f7ae3
|
||||
6: 0x7fbfb9ca3984 - rust_begin_unwind
|
||||
7: 0x7fbfb6ad55c3 - core::panicking::panic_fmt::h146c2ef4416c8c7b
|
||||
8: 0x7fbfba61abc5 - <rustc_middle[62c17eb200ed25ef]::query::on_disk_cache::CacheDecoder as rustc_span[e2902ef3f031f316]::SpanDecoder>::decode_span
|
||||
9: 0x7fbfba94bc1c - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::DefIdCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
10: 0x7fbfba94929a - rustc_query_impl[2b1ee272ecafb82c]::query_impl::def_span::get_query_incr::__rust_end_short_backtrace
|
||||
11: 0x7fbfbaa190c0 - rustc_middle[62c17eb200ed25ef]::query::plumbing::query_get_at::<rustc_query_system[4b3461eb5f3eee8]::query::caches::DefIdCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 8usize]>>>
|
||||
12: 0x7fbfbacaaf7d - <rustc_hir_analysis[198913e0276c9380]::coherence::inherent_impls_overlap::InherentOverlapChecker>::check_for_duplicate_items_in_impl
|
||||
13: 0x7fbfbb39e280 - rustc_hir_analysis[198913e0276c9380]::coherence::inherent_impls_overlap::crate_inherent_impls_overlap_check
|
||||
14: 0x7fbfbb39dc6d - rustc_query_impl[2b1ee272ecafb82c]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[2b1ee272ecafb82c]::query_impl::crate_inherent_impls_overlap_check::dynamic_query::{closure#2}::{closure#0}, rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>
|
||||
15: 0x7fbfbb39d1fd - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::SingleCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
16: 0x7fbfbb39c867 - rustc_query_impl[2b1ee272ecafb82c]::query_impl::crate_inherent_impls_overlap_check::get_query_incr::__rust_end_short_backtrace
|
||||
17: 0x7fbfba5bb6f3 - rustc_hir_analysis[198913e0276c9380]::check_crate
|
||||
18: 0x7fbfba5b1351 - rustc_interface[d7e86b952eb641e5]::passes::run_required_analyses
|
||||
19: 0x7fbfbb1bac1e - rustc_interface[d7e86b952eb641e5]::passes::analysis
|
||||
20: 0x7fbfbb1babf1 - rustc_query_impl[2b1ee272ecafb82c]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[2b1ee272ecafb82c]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>
|
||||
21: 0x7fbfbb39cecd - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::SingleCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
22: 0x7fbfbb39cb7a - rustc_query_impl[2b1ee272ecafb82c]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
|
||||
23: 0x7fbfbb1b30bc - rustc_interface[d7e86b952eb641e5]::interface::run_compiler::<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}
|
||||
24: 0x7fbfbb2c0504 - std[11ac8361619e45fd]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_with_globals<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_pool_with_globals<rustc_interface[d7e86b952eb641e5]::interface::run_compiler<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>
|
||||
25: 0x7fbfbb2c0b70 - <<std[11ac8361619e45fd]::thread::Builder>::spawn_unchecked_<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_with_globals<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_pool_with_globals<rustc_interface[d7e86b952eb641e5]::interface::run_compiler<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#1} as core[dcc560a250502550]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
|
||||
26: 0x7fbfbb2c0f6b - std::sys::pal::unix::thread::Thread::new::thread_start::h1921d0f3a7850262
|
||||
27: 0x7fbfbcbf8272 - start_thread
|
||||
28: 0x7fbfbcc73dcc - clone3
|
||||
29: 0x0 - <unknown>
|
||||
|
||||
|
||||
rustc version: 1.83.0-nightly (0ee7cb5e3 2024-09-10)
|
||||
platform: x86_64-unknown-linux-gnu
|
|
@ -1,37 +0,0 @@
|
|||
thread 'rustc' panicked at compiler/rustc_middle/src/query/on_disk_cache.rs:736:21:
|
||||
Failed to convert DefPathHash DefPathHash(Fingerprint(9597590199268592635, 17791879502897349522))
|
||||
stack backtrace:
|
||||
0: 0x77c2cca8d025 - std::backtrace::Backtrace::create::hbc256ff4bc983c0b
|
||||
1: 0x77c2cb28c865 - std::backtrace::Backtrace::force_capture::h1ebb6042c5b424a8
|
||||
2: 0x77c2ca3b2217 - std[11ac8361619e45fd]::panicking::update_hook::<alloc[1ed43557cf619c2]::boxed::Box<rustc_driver_impl[8c32a9dec5e4d0f0]::install_ice_hook::{closure#0}>>::{closure#0}
|
||||
3: 0x77c2cb2a3ee8 - std::panicking::rust_panic_with_hook::ha6cfc51100acb1ab
|
||||
4: 0x77c2cb2a3cb7 - std::panicking::begin_panic_handler::{{closure}}::he56e1efe5ba67ce1
|
||||
5: 0x77c2cb2a1699 - std::sys::backtrace::__rust_end_short_backtrace::hcc7bf1345a5f7ae3
|
||||
6: 0x77c2cb2a3984 - rust_begin_unwind
|
||||
7: 0x77c2c80d55c3 - core::panicking::panic_fmt::h146c2ef4416c8c7b
|
||||
8: 0x77c2cbc1abc5 - <rustc_middle[62c17eb200ed25ef]::query::on_disk_cache::CacheDecoder as rustc_span[e2902ef3f031f316]::SpanDecoder>::decode_span
|
||||
9: 0x77c2cbf4bc1c - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::DefIdCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
10: 0x77c2cbf4929a - rustc_query_impl[2b1ee272ecafb82c]::query_impl::def_span::get_query_incr::__rust_end_short_backtrace
|
||||
11: 0x77c2cc0190c0 - rustc_middle[62c17eb200ed25ef]::query::plumbing::query_get_at::<rustc_query_system[4b3461eb5f3eee8]::query::caches::DefIdCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 8usize]>>>
|
||||
12: 0x77c2cc2aaf7d - <rustc_hir_analysis[198913e0276c9380]::coherence::inherent_impls_overlap::InherentOverlapChecker>::check_for_duplicate_items_in_impl
|
||||
13: 0x77c2cc99e280 - rustc_hir_analysis[198913e0276c9380]::coherence::inherent_impls_overlap::crate_inherent_impls_overlap_check
|
||||
14: 0x77c2cc99dc6d - rustc_query_impl[2b1ee272ecafb82c]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[2b1ee272ecafb82c]::query_impl::crate_inherent_impls_overlap_check::dynamic_query::{closure#2}::{closure#0}, rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>
|
||||
15: 0x77c2cc99d1fd - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::SingleCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
16: 0x77c2cc99c867 - rustc_query_impl[2b1ee272ecafb82c]::query_impl::crate_inherent_impls_overlap_check::get_query_incr::__rust_end_short_backtrace
|
||||
17: 0x77c2cbbbb6f3 - rustc_hir_analysis[198913e0276c9380]::check_crate
|
||||
18: 0x77c2cbbb1351 - rustc_interface[d7e86b952eb641e5]::passes::run_required_analyses
|
||||
19: 0x77c2cc7bac1e - rustc_interface[d7e86b952eb641e5]::passes::analysis
|
||||
20: 0x77c2cc7babf1 - rustc_query_impl[2b1ee272ecafb82c]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[2b1ee272ecafb82c]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>
|
||||
21: 0x77c2cc99cecd - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::SingleCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
22: 0x77c2cc99cb7a - rustc_query_impl[2b1ee272ecafb82c]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
|
||||
23: 0x77c2cc7b30bc - rustc_interface[d7e86b952eb641e5]::interface::run_compiler::<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}
|
||||
24: 0x77c2cc8c0504 - std[11ac8361619e45fd]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_with_globals<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_pool_with_globals<rustc_interface[d7e86b952eb641e5]::interface::run_compiler<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>
|
||||
25: 0x77c2cc8c0b70 - <<std[11ac8361619e45fd]::thread::Builder>::spawn_unchecked_<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_with_globals<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_pool_with_globals<rustc_interface[d7e86b952eb641e5]::interface::run_compiler<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#1} as core[dcc560a250502550]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
|
||||
26: 0x77c2cc8c0f6b - std::sys::pal::unix::thread::Thread::new::thread_start::h1921d0f3a7850262
|
||||
27: 0x77c2ce089272 - start_thread
|
||||
28: 0x77c2ce104dcc - clone3
|
||||
29: 0x0 - <unknown>
|
||||
|
||||
|
||||
rustc version: 1.83.0-nightly (0ee7cb5e3 2024-09-10)
|
||||
platform: x86_64-unknown-linux-gnu
|
|
@ -1,37 +0,0 @@
|
|||
thread 'rustc' panicked at compiler/rustc_middle/src/query/on_disk_cache.rs:736:21:
|
||||
Failed to convert DefPathHash DefPathHash(Fingerprint(9597590199268592635, 17791879502897349522))
|
||||
stack backtrace:
|
||||
0: 0x704a8948d025 - std::backtrace::Backtrace::create::hbc256ff4bc983c0b
|
||||
1: 0x704a87c8c865 - std::backtrace::Backtrace::force_capture::h1ebb6042c5b424a8
|
||||
2: 0x704a86db2217 - std[11ac8361619e45fd]::panicking::update_hook::<alloc[1ed43557cf619c2]::boxed::Box<rustc_driver_impl[8c32a9dec5e4d0f0]::install_ice_hook::{closure#0}>>::{closure#0}
|
||||
3: 0x704a87ca3ee8 - std::panicking::rust_panic_with_hook::ha6cfc51100acb1ab
|
||||
4: 0x704a87ca3cb7 - std::panicking::begin_panic_handler::{{closure}}::he56e1efe5ba67ce1
|
||||
5: 0x704a87ca1699 - std::sys::backtrace::__rust_end_short_backtrace::hcc7bf1345a5f7ae3
|
||||
6: 0x704a87ca3984 - rust_begin_unwind
|
||||
7: 0x704a84ad55c3 - core::panicking::panic_fmt::h146c2ef4416c8c7b
|
||||
8: 0x704a8861abc5 - <rustc_middle[62c17eb200ed25ef]::query::on_disk_cache::CacheDecoder as rustc_span[e2902ef3f031f316]::SpanDecoder>::decode_span
|
||||
9: 0x704a8894bc1c - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::DefIdCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
10: 0x704a8894929a - rustc_query_impl[2b1ee272ecafb82c]::query_impl::def_span::get_query_incr::__rust_end_short_backtrace
|
||||
11: 0x704a88a190c0 - rustc_middle[62c17eb200ed25ef]::query::plumbing::query_get_at::<rustc_query_system[4b3461eb5f3eee8]::query::caches::DefIdCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 8usize]>>>
|
||||
12: 0x704a88caaf7d - <rustc_hir_analysis[198913e0276c9380]::coherence::inherent_impls_overlap::InherentOverlapChecker>::check_for_duplicate_items_in_impl
|
||||
13: 0x704a8939e280 - rustc_hir_analysis[198913e0276c9380]::coherence::inherent_impls_overlap::crate_inherent_impls_overlap_check
|
||||
14: 0x704a8939dc6d - rustc_query_impl[2b1ee272ecafb82c]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[2b1ee272ecafb82c]::query_impl::crate_inherent_impls_overlap_check::dynamic_query::{closure#2}::{closure#0}, rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>
|
||||
15: 0x704a8939d1fd - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::SingleCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
16: 0x704a8939c867 - rustc_query_impl[2b1ee272ecafb82c]::query_impl::crate_inherent_impls_overlap_check::get_query_incr::__rust_end_short_backtrace
|
||||
17: 0x704a885bb6f3 - rustc_hir_analysis[198913e0276c9380]::check_crate
|
||||
18: 0x704a885b1351 - rustc_interface[d7e86b952eb641e5]::passes::run_required_analyses
|
||||
19: 0x704a891bac1e - rustc_interface[d7e86b952eb641e5]::passes::analysis
|
||||
20: 0x704a891babf1 - rustc_query_impl[2b1ee272ecafb82c]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[2b1ee272ecafb82c]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>
|
||||
21: 0x704a8939cecd - rustc_query_system[4b3461eb5f3eee8]::query::plumbing::try_execute_query::<rustc_query_impl[2b1ee272ecafb82c]::DynamicConfig<rustc_query_system[4b3461eb5f3eee8]::query::caches::SingleCache<rustc_middle[62c17eb200ed25ef]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[2b1ee272ecafb82c]::plumbing::QueryCtxt, true>
|
||||
22: 0x704a8939cb7a - rustc_query_impl[2b1ee272ecafb82c]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
|
||||
23: 0x704a891b30bc - rustc_interface[d7e86b952eb641e5]::interface::run_compiler::<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}
|
||||
24: 0x704a892c0504 - std[11ac8361619e45fd]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_with_globals<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_pool_with_globals<rustc_interface[d7e86b952eb641e5]::interface::run_compiler<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>
|
||||
25: 0x704a892c0b70 - <<std[11ac8361619e45fd]::thread::Builder>::spawn_unchecked_<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_with_globals<rustc_interface[d7e86b952eb641e5]::util::run_in_thread_pool_with_globals<rustc_interface[d7e86b952eb641e5]::interface::run_compiler<core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>, rustc_driver_impl[8c32a9dec5e4d0f0]::run_compiler::{closure#0}>::{closure#1}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[dcc560a250502550]::result::Result<(), rustc_span[e2902ef3f031f316]::ErrorGuaranteed>>::{closure#1} as core[dcc560a250502550]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
|
||||
26: 0x704a892c0f6b - std::sys::pal::unix::thread::Thread::new::thread_start::h1921d0f3a7850262
|
||||
27: 0x704a8ac0b272 - start_thread
|
||||
28: 0x704a8ac86dcc - clone3
|
||||
29: 0x0 - <unknown>
|
||||
|
||||
|
||||
rustc version: 1.83.0-nightly (0ee7cb5e3 2024-09-10)
|
||||
platform: x86_64-unknown-linux-gnu
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
pub mod web;
|
||||
|
|
168
src/billing/adapters/input/web/bill.rs
Normal file
168
src/billing/adapters/input/web/bill.rs
Normal file
|
@ -0,0 +1,168 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{get, http::header::ContentType, post, web, HttpRequest, HttpResponse, Responder};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::errors::*;
|
||||
use super::types;
|
||||
use crate::billing::domain::add_store_command::AddStoreCommandBuilder;
|
||||
use crate::billing::domain::{add_bill_command::*, bill_updated_event, commands::BillingCommand};
|
||||
use crate::utils::uuid::WebGetUUIDInterfaceObj;
|
||||
|
||||
pub fn services(cfg: &mut web::ServiceConfig) {
|
||||
cfg.service(add_bill_submit_handler);
|
||||
cfg.service(add_bill_page_handler);
|
||||
cfg.service(add_store_page_handler);
|
||||
cfg.service(add_store_submit_handler);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||
struct WebAddBillPayload {
|
||||
store_id: Uuid,
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[get("/billing/store/add")]
|
||||
#[tracing::instrument(name = "add store page handler", skip())]
|
||||
//async fn add_bill_page_handler(_: Identity) -> WebJsonRepsonse<impl Responder> {
|
||||
async fn add_store_page_handler() -> WebJsonRepsonse<impl Responder> {
|
||||
let page = r#"
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<form action="/billing/store/add" method="post">
|
||||
<button type="submit">
|
||||
Create Store
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"#;
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.insert_header(ContentType::html())
|
||||
.body(page))
|
||||
}
|
||||
|
||||
const UUID: Uuid = uuid::uuid!("67e55044-10b1-426f-9247-bb680e5fe0c8");
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[post("/billing/store/add")]
|
||||
#[tracing::instrument(
|
||||
name = "add store handler",
|
||||
skip(billing_store_cqrs_exec, billing_store_cqrs_view, uuid_generator)
|
||||
)]
|
||||
async fn add_store_submit_handler(
|
||||
billing_store_cqrs_exec: types::WebBillingStoreCqrsExec,
|
||||
billing_store_cqrs_view: types::WebBillingStoreCqrsView,
|
||||
uuid_generator: WebGetUUIDInterfaceObj,
|
||||
req: HttpRequest,
|
||||
// id: Identity,
|
||||
) -> WebJsonRepsonse<impl Responder> {
|
||||
// let user_id = Uuid::parse_str(&id.id().unwrap()).unwrap();
|
||||
let user_id = UUID;
|
||||
|
||||
let store_uuid = UUID;
|
||||
let store_uuid_str = store_uuid.to_string();
|
||||
let cmd = AddStoreCommandBuilder::default()
|
||||
.name("foo".into())
|
||||
.owner(user_id)
|
||||
.store_id(UUID)
|
||||
.address(None)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
billing_store_cqrs_exec
|
||||
.execute(&store_uuid_str, BillingCommand::AddStore(cmd))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let store = billing_store_cqrs_view
|
||||
.load(&store_uuid_str)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
Ok(HttpResponse::Ok().json(store))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[get("/billing/bill/add")]
|
||||
#[tracing::instrument(name = "add bill page handler", skip())]
|
||||
//async fn add_bill_page_handler(_: Identity) -> WebJsonRepsonse<impl Responder> {
|
||||
async fn add_bill_page_handler() -> WebJsonRepsonse<impl Responder> {
|
||||
let page = r#"
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
Token Refreshed
|
||||
<form action="/billing/bill/add" method="post">
|
||||
<label> Store ID <input type="text" name="store_id" id="store_id" /></label>
|
||||
<button type="submit">
|
||||
Refresh Token
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"#;
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
.insert_header(ContentType::html())
|
||||
.body(page))
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[post("/billing/bill/add")]
|
||||
#[tracing::instrument(
|
||||
name = "add bill handler",
|
||||
skip(billing_bill_cqrs_exec, billing_bill_cqrs_view,)
|
||||
)]
|
||||
async fn add_bill_submit_handler(
|
||||
billing_bill_cqrs_exec: types::WebBillingBillCqrsExec,
|
||||
billing_bill_cqrs_view: types::WebBillingBillCqrsView,
|
||||
req: HttpRequest,
|
||||
// id: Identity,
|
||||
payload: web::Form<WebAddBillPayload>,
|
||||
) -> WebJsonRepsonse<impl Responder> {
|
||||
// let user_id = Uuid::parse_str(&id.id().unwrap()).unwrap();
|
||||
let user_id = Uuid::new_v4();
|
||||
|
||||
let bill_uuid = Uuid::new_v4();
|
||||
let bill_uuid_str = bill_uuid.to_string();
|
||||
let cmd = AddBillCommandBuilder::default()
|
||||
.adding_by(user_id)
|
||||
.bill_id(bill_uuid)
|
||||
.store_id(payload.store_id)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
billing_bill_cqrs_exec
|
||||
.execute(&bill_uuid_str, BillingCommand::AddBill(cmd))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let bill = billing_bill_cqrs_view
|
||||
.load(&bill_uuid_str)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
Ok(HttpResponse::Ok().json(bill))
|
||||
}
|
75
src/billing/adapters/input/web/errors.rs
Normal file
75
src/billing/adapters/input/web/errors.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::{HttpResponse, ResponseError};
|
||||
use derive_more::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::billing::application::services::errors::*;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
|
||||
struct ErrorResponse {
|
||||
error: String,
|
||||
}
|
||||
|
||||
impl From<WebError> for ErrorResponse {
|
||||
fn from(value: WebError) -> Self {
|
||||
ErrorResponse {
|
||||
error: serde_json::to_string(&value).unwrap_or_else(|_| {
|
||||
log::error!("Unable to serialize error");
|
||||
"Unable to serialize error".into()
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum WebError {
|
||||
InternalError,
|
||||
BillNotFound,
|
||||
StoreNotFound,
|
||||
LineItemNotFound,
|
||||
BadRequest,
|
||||
}
|
||||
|
||||
impl From<BillingError> for WebError {
|
||||
fn from(v: BillingError) -> Self {
|
||||
match v {
|
||||
BillingError::BillIDNotFound => Self::BillNotFound,
|
||||
BillingError::InternalError => Self::InternalError,
|
||||
BillingError::DuplicateStoreName => Self::InternalError,
|
||||
BillingError::DuplicateBillID => Self::InternalError,
|
||||
BillingError::DuplicateLineItemID => Self::InternalError,
|
||||
BillingError::DuplicateStoreID => Self::InternalError,
|
||||
BillingError::StoreIDNotFound => Self::StoreNotFound,
|
||||
BillingError::LineItemIDNotFound => Self::LineItemNotFound,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ResponseError for WebError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self {
|
||||
Self::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||
Self::StoreNotFound => StatusCode::NOT_FOUND,
|
||||
Self::LineItemNotFound => StatusCode::NOT_FOUND,
|
||||
Self::BillNotFound => StatusCode::NOT_FOUND,
|
||||
Self::BadRequest => StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
fn error_response(&self) -> actix_web::HttpResponse {
|
||||
let e: ErrorResponse = self.clone().into();
|
||||
match self {
|
||||
Self::InternalError => HttpResponse::InternalServerError().json(e),
|
||||
Self::StoreNotFound => HttpResponse::NotFound().json(e),
|
||||
Self::LineItemNotFound => HttpResponse::NotFound().json(e),
|
||||
Self::BillNotFound => HttpResponse::BadRequest().json(e),
|
||||
Self::BadRequest => HttpResponse::BadRequest().json(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type WebJsonRepsonse<V> = Result<V, WebError>;
|
28
src/billing/adapters/input/web/mod.rs
Normal file
28
src/billing/adapters/input/web/mod.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web;
|
||||
|
||||
use crate::billing::adapters::types;
|
||||
|
||||
mod bill;
|
||||
mod errors;
|
||||
mod routes;
|
||||
|
||||
pub use errors::WebJsonRepsonse;
|
||||
|
||||
pub use routes::RoutesRepository;
|
||||
|
||||
pub fn load_ctx() -> impl FnOnce(&mut web::ServiceConfig) {
|
||||
let routes = types::WebBillingRoutesRepository::new(Arc::new(RoutesRepository::default()));
|
||||
|
||||
let f = move |cfg: &mut web::ServiceConfig| {
|
||||
cfg.app_data(routes);
|
||||
cfg.configure(bill::services);
|
||||
};
|
||||
|
||||
Box::new(f)
|
||||
}
|
67
src/billing/adapters/input/web/routes.rs
Normal file
67
src/billing/adapters/input/web/routes.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct RoutesRepository {
|
||||
add_bill: String,
|
||||
update_bill: String,
|
||||
delete_bill: String,
|
||||
compute_total_price_for_bill: String,
|
||||
|
||||
add_line_item: String,
|
||||
update_line_item: String,
|
||||
delete_line_item: String,
|
||||
}
|
||||
|
||||
impl Default for RoutesRepository {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
add_bill: "/billing/bill/add".into(),
|
||||
update_bill: "/billing/bill/{bill_uuid}".into(),
|
||||
delete_bill: "/billing/bill/{bill_uuid}".into(),
|
||||
compute_total_price_for_bill: "/billing/bill/{bill_uuid}/compute-total".into(),
|
||||
|
||||
add_line_item: "/billing/bill/{bill_id}/line_item/add".into(),
|
||||
update_line_item: "/billing/bill/{bill_id}/line_item/{line_item_uuid}".into(),
|
||||
delete_line_item: "/billing/bill/{bill_id}/line_item/{line_item_uuid}".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RoutesRepository {
|
||||
pub fn update_bill(&self, bill_id: Uuid) -> String {
|
||||
self.update_bill
|
||||
.replace("{bill_uuid}", &bill_id.to_string())
|
||||
}
|
||||
|
||||
pub fn delete_bill(&self, bill_id: Uuid) -> String {
|
||||
self.delete_bill
|
||||
.replace("{bill_uuid}", &bill_id.to_string())
|
||||
}
|
||||
|
||||
pub fn compute_total_price_for_bill(&self, bill_id: Uuid) -> String {
|
||||
self.compute_total_price_for_bill
|
||||
.replace("{bill_uuid}", &bill_id.to_string())
|
||||
}
|
||||
|
||||
pub fn add_line_item(&self, bill_id: Uuid) -> String {
|
||||
self.add_line_item
|
||||
.replace("{bill_uuid}", &bill_id.to_string())
|
||||
}
|
||||
|
||||
pub fn update_line_item(&self, bill_id: Uuid, line_item_uuid: Uuid) -> String {
|
||||
self.update_line_item
|
||||
.replace("{bill_uuid}", &bill_id.to_string())
|
||||
.replace("{line_item_uuid}", &line_item_uuid.to_string())
|
||||
}
|
||||
|
||||
pub fn delete_line_item(&self, bill_id: Uuid, line_item_uuid: Uuid) -> String {
|
||||
self.delete_line_item
|
||||
.replace("{bill_uuid}", &bill_id.to_string())
|
||||
.replace("{line_item_uuid}", &line_item_uuid.to_string())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,87 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web::{self, Data};
|
||||
use cqrs_es::{persist::ViewRepository, EventEnvelope, Query, View};
|
||||
use postgres_es::PostgresCqrs;
|
||||
use sqlx::postgres::PgPool;
|
||||
|
||||
use crate::billing::{
|
||||
application::{
|
||||
port::output::db::{
|
||||
bill_id_exists::BillIDExistsDBPortObj,
|
||||
get_line_items_for_bill_id::GetLineItemsForBillIDDBPortObj,
|
||||
line_item_id_exists::LineItemIDExistsDBPortObj, next_token_id::NextTokenIDDBPortObj,
|
||||
store_id_exists::StoreIDExistsDBPortObj, store_name_exists::StoreNameExistsDBPortObj,
|
||||
},
|
||||
services::{BillingServices, BillingServicesObj},
|
||||
},
|
||||
domain::{bill_aggregate::Bill, line_item_aggregate::LineItem, store_aggregate::Store},
|
||||
};
|
||||
use crate::settings::Settings;
|
||||
use output::db::postgres::{bill_view, line_item_view, store_view, BillingDBPostgresAdapter};
|
||||
|
||||
mod input;
|
||||
mod output;
|
||||
mod types;
|
||||
|
||||
pub fn load_adapters(pool: PgPool, settings: Settings) -> impl FnOnce(&mut web::ServiceConfig) {
|
||||
// init DB
|
||||
let db = BillingDBPostgresAdapter::new(pool.clone());
|
||||
let db_bill_id_exists: BillIDExistsDBPortObj = Arc::new(db.clone());
|
||||
let db_line_item_id_exists: LineItemIDExistsDBPortObj = Arc::new(db.clone());
|
||||
let db_store_id_exists: StoreIDExistsDBPortObj = Arc::new(db.clone());
|
||||
let db_store_name_exists: StoreNameExistsDBPortObj = Arc::new(db.clone());
|
||||
let db_get_line_items_for_bill_id: GetLineItemsForBillIDDBPortObj = Arc::new(db.clone());
|
||||
let db_next_token_id: NextTokenIDDBPortObj = Arc::new(db.clone());
|
||||
|
||||
// init services
|
||||
|
||||
let services: BillingServicesObj = Arc::new(BillingServices::new(
|
||||
db_bill_id_exists.clone(),
|
||||
db_line_item_id_exists.clone(),
|
||||
db_store_id_exists.clone(),
|
||||
db_store_name_exists.clone(),
|
||||
db_get_line_items_for_bill_id.clone(),
|
||||
db_next_token_id.clone(),
|
||||
));
|
||||
|
||||
let (bill_cqrs_exec, bill_cqrs_query) = bill_view::init_cqrs(db.clone(), services.clone());
|
||||
let (store_cqrs_exec, store_cqrs_query) = store_view::init_cqrs(db.clone(), services.clone());
|
||||
let (line_item_cqrs_exec, line_item_cqrs_query) =
|
||||
line_item_view::init_cqrs(db.clone(), services.clone());
|
||||
|
||||
let f = move |cfg: &mut web::ServiceConfig| {
|
||||
cfg.configure(input::web::load_ctx());
|
||||
|
||||
cfg.app_data(Data::new(bill_cqrs_exec.clone()));
|
||||
cfg.app_data(Data::new(bill_cqrs_query.clone()));
|
||||
|
||||
cfg.app_data(Data::new(store_cqrs_exec.clone()));
|
||||
cfg.app_data(Data::new(store_cqrs_query.clone()));
|
||||
|
||||
cfg.app_data(Data::new(line_item_cqrs_exec.clone()));
|
||||
cfg.app_data(Data::new(line_item_cqrs_query.clone()));
|
||||
};
|
||||
|
||||
Box::new(f)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::db::migrate::*;
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn billing_load_adapters() {
|
||||
let settings = crate::settings::tests::get_settings().await;
|
||||
settings.create_db().await;
|
||||
|
||||
let db = crate::db::sqlx_postgres::Postgres::init(&settings.database.url).await;
|
||||
db.migrate().await;
|
||||
|
||||
load_adapters(db.pool.clone(), settings.clone());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
mod postgres;
|
||||
pub(crate) mod postgres;
|
||||
|
|
|
@ -3,16 +3,20 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cqrs_es::persist::{PersistenceError, ViewContext, ViewRepository};
|
||||
use cqrs_es::{EventEnvelope, Query, View};
|
||||
use postgres_es::PostgresCqrs;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use time::OffsetDateTime;
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::errors::*;
|
||||
use super::BillingDBPostgresAdapter;
|
||||
use crate::billing::adapters::types::{BillingBillCqrsExec, BillingBillCqrsView};
|
||||
use crate::billing::application::services::BillingServicesObj;
|
||||
use crate::billing::domain::bill_aggregate::{Bill, BillBuilder};
|
||||
use crate::billing::domain::events::BillingEvent;
|
||||
use crate::types::currency::{self, Currency, PriceBuilder};
|
||||
|
@ -311,12 +315,24 @@ impl Query<Bill> for BillingDBPostgresAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init_cqrs(
|
||||
db: BillingDBPostgresAdapter,
|
||||
services: BillingServicesObj,
|
||||
) -> (BillingBillCqrsExec, BillingBillCqrsView) {
|
||||
let queries: Vec<Box<dyn Query<Bill>>> = vec![Box::new(db.clone())];
|
||||
|
||||
let pool = db.pool.clone();
|
||||
|
||||
(
|
||||
Arc::new(postgres_es::postgres_cqrs(pool.clone(), queries, services)),
|
||||
Arc::new(db.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use postgres_es::PostgresCqrs;
|
||||
|
||||
use crate::{
|
||||
billing::{
|
||||
application::services::{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cqrs_es::persist::{PersistenceError, ViewContext, ViewRepository};
|
||||
|
@ -13,6 +13,8 @@ use uuid::Uuid;
|
|||
|
||||
use super::errors::*;
|
||||
use super::BillingDBPostgresAdapter;
|
||||
use crate::billing::adapters::types::{BillingLineItemCqrsExec, BillingLineItemCqrsView};
|
||||
use crate::billing::application::services::BillingServicesObj;
|
||||
use crate::billing::domain::events::BillingEvent;
|
||||
use crate::billing::domain::line_item_aggregate::*;
|
||||
use crate::types::currency::*;
|
||||
|
@ -363,6 +365,20 @@ impl Query<LineItem> for BillingDBPostgresAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init_cqrs(
|
||||
db: BillingDBPostgresAdapter,
|
||||
services: BillingServicesObj,
|
||||
) -> (BillingLineItemCqrsExec, BillingLineItemCqrsView) {
|
||||
let queries: Vec<Box<dyn Query<LineItem>>> = vec![Box::new(db.clone())];
|
||||
|
||||
let pool = db.pool.clone();
|
||||
|
||||
(
|
||||
Arc::new(postgres_es::postgres_cqrs(pool.clone(), queries, services)),
|
||||
Arc::new(db.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -8,19 +8,19 @@ use sqlx::postgres::PgPool;
|
|||
use crate::db::{migrate::RunMigrations, sqlx_postgres::Postgres};
|
||||
|
||||
mod bill_id_exists;
|
||||
mod bill_view;
|
||||
pub(crate) mod bill_view;
|
||||
mod errors;
|
||||
mod get_line_items_for_bill_id;
|
||||
mod line_item_id_exists;
|
||||
mod line_item_view;
|
||||
pub(crate) mod line_item_view;
|
||||
mod next_token_id;
|
||||
mod store_id_exists;
|
||||
mod store_name_exists;
|
||||
mod store_view;
|
||||
pub(crate) mod store_view;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BillingDBPostgresAdapter {
|
||||
pool: PgPool,
|
||||
pub(crate) pool: PgPool,
|
||||
}
|
||||
|
||||
impl BillingDBPostgresAdapter {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use cqrs_es::persist::{PersistenceError, ViewContext, ViewRepository};
|
||||
|
@ -10,6 +11,8 @@ use uuid::Uuid;
|
|||
|
||||
use super::errors::*;
|
||||
use super::BillingDBPostgresAdapter;
|
||||
use crate::billing::adapters::types::{BillingStoreCqrsExec, BillingStoreCqrsView};
|
||||
use crate::billing::application::services::BillingServicesObj;
|
||||
use crate::billing::domain::events::BillingEvent;
|
||||
use crate::billing::domain::store_aggregate::*;
|
||||
use crate::utils::parse_aggregate_id::parse_aggregate_id;
|
||||
|
@ -216,6 +219,20 @@ impl Query<Store> for BillingDBPostgresAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn init_cqrs(
|
||||
db: BillingDBPostgresAdapter,
|
||||
services: BillingServicesObj,
|
||||
) -> (BillingStoreCqrsExec, BillingStoreCqrsView) {
|
||||
let queries: Vec<Box<dyn Query<Store>>> = vec![Box::new(db.clone())];
|
||||
|
||||
let pool = db.pool.clone();
|
||||
|
||||
(
|
||||
Arc::new(postgres_es::postgres_cqrs(pool.clone(), queries, services)),
|
||||
Arc::new(db.clone()),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
mod db;
|
||||
pub(crate) mod db;
|
||||
|
|
45
src/billing/adapters/types.rs
Normal file
45
src/billing/adapters/types.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use actix_web::web::Data;
|
||||
use cqrs_es::persist::ViewRepository;
|
||||
use postgres_es::PostgresCqrs;
|
||||
|
||||
use crate::billing::{
|
||||
adapters::{
|
||||
input::web::RoutesRepository,
|
||||
output::db::postgres::{
|
||||
bill_view::BillView, line_item_view::LineItemView, store_view::StoreView,
|
||||
BillingDBPostgresAdapter,
|
||||
},
|
||||
},
|
||||
application::services::BillingServicesObj,
|
||||
domain::{bill_aggregate::Bill, line_item_aggregate::LineItem, store_aggregate::Store},
|
||||
};
|
||||
|
||||
pub type WebBillingRoutesRepository = Data<Arc<RoutesRepository>>;
|
||||
|
||||
pub type WebBillingServiceObj = Data<BillingServicesObj>;
|
||||
|
||||
pub type BillingBillCqrsExec = Arc<PostgresCqrs<Bill>>;
|
||||
pub type WebBillingBillCqrsExec = Data<BillingBillCqrsExec>;
|
||||
pub type BillingBillCqrsView = Arc<dyn ViewRepository<BillView, Bill>>;
|
||||
pub type WebBillingBillCqrsView = Data<BillingBillCqrsView>;
|
||||
|
||||
pub type BillingLineItemCqrsExec = Arc<PostgresCqrs<LineItem>>;
|
||||
pub type WebBillingLineItemCqrsExec = Data<BillingLineItemCqrsExec>;
|
||||
pub type BillingLineItemCqrsView = Arc<dyn ViewRepository<LineItemView, LineItem>>;
|
||||
pub type WebBillingLineItemCqrsView = Data<BillingLineItemCqrsView>;
|
||||
|
||||
pub type BillingStoreCqrsExec = Arc<PostgresCqrs<Store>>;
|
||||
pub type WebBillingStoreCqrsExec = Data<BillingStoreCqrsExec>;
|
||||
pub type BillingStoreCqrsView = Arc<dyn ViewRepository<StoreView, Store>>;
|
||||
pub type WebBillingStoreCqrsView = Data<BillingStoreCqrsView>;
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
use std::sync::Arc;
|
||||
|
||||
use derive_builder::Builder;
|
||||
use mockall::predicate::*;
|
||||
|
@ -20,6 +21,23 @@ pub mod update_line_item_service;
|
|||
pub mod update_store_service;
|
||||
// TODO: 2. reset token number for store_id cronjob
|
||||
|
||||
use add_bill_service::AddBillServiceBuilder;
|
||||
use add_line_item_service::AddLineItemServiceBuilder;
|
||||
use add_store_service::AddStoreServiceBuilder;
|
||||
use compute_bill_total_price_service::ComputeBillTotalPriceBillServiceBuilder;
|
||||
use delete_bill_service::DeleteBillServiceBuilder;
|
||||
use delete_line_item_service::DeleteLineItemServiceBuilder;
|
||||
use update_bill_service::UpdateBillServiceBuilder;
|
||||
use update_line_item_service::UpdateLineItemServiceBuilder;
|
||||
use update_store_service::UpdateStoreServiceBuilder;
|
||||
|
||||
use crate::billing::application::port::output::db::{
|
||||
bill_id_exists::BillIDExistsDBPortObj,
|
||||
get_line_items_for_bill_id::GetLineItemsForBillIDDBPortObj,
|
||||
line_item_id_exists::LineItemIDExistsDBPortObj, next_token_id::NextTokenIDDBPortObj,
|
||||
store_id_exists::StoreIDExistsDBPortObj, store_name_exists::StoreNameExistsDBPortObj,
|
||||
};
|
||||
|
||||
#[automock]
|
||||
pub trait BillingServicesInterface: Send + Sync {
|
||||
fn add_bill(&self) -> add_bill_service::AddBillServiceObj;
|
||||
|
@ -35,6 +53,8 @@ pub trait BillingServicesInterface: Send + Sync {
|
|||
) -> compute_bill_total_price_service::ComputeBillTotalPriceBillServiceObj;
|
||||
}
|
||||
|
||||
pub type BillingServicesObj = std::sync::Arc<dyn BillingServicesInterface>;
|
||||
|
||||
#[derive(Clone, Builder)]
|
||||
pub struct BillingServices {
|
||||
add_bill: add_bill_service::AddBillServiceObj,
|
||||
|
@ -81,3 +101,109 @@ impl BillingServicesInterface for BillingServices {
|
|||
self.compute_total_price_for_bill.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl BillingServices {
|
||||
pub fn new(
|
||||
db_bill_id_exists: BillIDExistsDBPortObj,
|
||||
db_line_item_id_exists: LineItemIDExistsDBPortObj,
|
||||
db_store_id_exists: StoreIDExistsDBPortObj,
|
||||
db_store_name_exists: StoreNameExistsDBPortObj,
|
||||
db_get_line_items_for_bill_id: GetLineItemsForBillIDDBPortObj,
|
||||
db_next_token_id: NextTokenIDDBPortObj,
|
||||
) -> Self {
|
||||
let services = BillingServicesBuilder::default()
|
||||
.add_bill(Arc::new(
|
||||
AddBillServiceBuilder::default()
|
||||
.db_next_token_id(db_next_token_id.clone())
|
||||
.db_bill_id_exists(db_bill_id_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.add_store(Arc::new(
|
||||
AddStoreServiceBuilder::default()
|
||||
.db_store_id_exists(db_store_id_exists.clone())
|
||||
.db_store_name_exists(db_store_name_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.update_store(Arc::new(
|
||||
UpdateStoreServiceBuilder::default()
|
||||
.db_store_id_exists(db_store_id_exists.clone())
|
||||
.db_store_name_exists(db_store_name_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.add_line_item(Arc::new(
|
||||
AddLineItemServiceBuilder::default()
|
||||
.db_line_item_id_exists(db_line_item_id_exists.clone())
|
||||
.db_bill_id_exists(db_bill_id_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.update_line_item(Arc::new(
|
||||
UpdateLineItemServiceBuilder::default()
|
||||
.db_line_item_id_exists(db_line_item_id_exists.clone())
|
||||
.db_bill_id_exists(db_bill_id_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.delete_line_item(Arc::new(
|
||||
DeleteLineItemServiceBuilder::default()
|
||||
.db_line_item_id_exists(db_line_item_id_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.update_bill(Arc::new(
|
||||
UpdateBillServiceBuilder::default()
|
||||
.db_bill_id_exists(db_bill_id_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.delete_bill(Arc::new(
|
||||
DeleteBillServiceBuilder::default()
|
||||
.db_bill_id_exists(db_bill_id_exists.clone())
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.compute_total_price_for_bill(Arc::new(
|
||||
ComputeBillTotalPriceBillServiceBuilder::default()
|
||||
.db_bill_id_exists(db_bill_id_exists.clone())
|
||||
.db_get_line_items_for_bill_id(db_get_line_items_for_bill_id)
|
||||
.build()
|
||||
.unwrap(),
|
||||
))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
services
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
billing::application::port::output::db::{
|
||||
bill_id_exists::mock_bill_id_exists_db_port_true,
|
||||
get_line_items_for_bill_id::mock_get_line_items_for_bill_id_db_port_no_line_items,
|
||||
line_item_id_exists::mock_line_item_id_exists_db_port_true,
|
||||
next_token_id::mock_next_token_id_db_port,
|
||||
store_id_exists::mock_store_id_exists_db_port_true,
|
||||
store_name_exists::mock_store_name_exists_db_port_true,
|
||||
},
|
||||
db::migrate::*,
|
||||
tests::bdd::IS_NEVER_CALLED,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn billing_services_builder_works() {
|
||||
BillingServices::new(
|
||||
mock_bill_id_exists_db_port_true(IS_NEVER_CALLED),
|
||||
mock_line_item_id_exists_db_port_true(IS_NEVER_CALLED),
|
||||
mock_store_id_exists_db_port_true(IS_NEVER_CALLED),
|
||||
mock_store_name_exists_db_port_true(IS_NEVER_CALLED),
|
||||
mock_get_line_items_for_bill_id_db_port_no_line_items(IS_NEVER_CALLED),
|
||||
mock_next_token_id_db_port(IS_NEVER_CALLED),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
mod adapters;
|
||||
pub(crate) mod adapters;
|
||||
mod application;
|
||||
mod domain;
|
||||
|
|
|
@ -58,6 +58,10 @@ async fn main() {
|
|||
.wrap(
|
||||
middleware::DefaultHeaders::new().add(("Permissions-Policy", "interest-cohort=()")),
|
||||
)
|
||||
.configure(billing::adapters::load_adapters(
|
||||
db.pool.clone(),
|
||||
settings.clone(),
|
||||
))
|
||||
// .configure(auth::adapter::load_adapters(db.pool.clone(), &settings))
|
||||
.configure(utils::random_string::GenerateRandomString::inject())
|
||||
.configure(utils::uuid::GenerateUUID::inject())
|
||||
|
|
Loading…
Reference in a new issue