1use std::sync::Arc;
55
56use dwn_core::{
57 message::{Message, descriptor::Descriptor},
58 reply::Reply,
59 store::{DataStore, RecordStore},
60};
61use reqwest::StatusCode;
62use tracing::debug;
63use xdid::core::did::Did;
64
65pub use dwn_core as core;
66
67pub mod stores {
68 #[cfg(feature = "native_db")]
69 pub use dwn_native_db::*;
70}
71
72mod actor;
73mod handlers;
74
75pub use actor::*;
76
77use crate::handlers::validation::ValidationResult;
78
79#[derive(Clone)]
80pub struct Dwn {
81 pub data_store: Arc<dyn DataStore>,
82 pub record_store: Arc<dyn RecordStore>,
83}
84
85impl<T: DataStore + RecordStore + Clone + 'static> From<T> for Dwn {
86 fn from(value: T) -> Self {
87 Self::new(Arc::new(value.clone()), Arc::new(value))
88 }
89}
90
91struct ProcessContext<'a> {
92 pub rs: &'a dyn RecordStore,
93 pub ds: &'a dyn DataStore,
94 pub validation: ValidationResult,
95 pub target: &'a Did,
96 pub msg: Message,
97}
98
99impl Dwn {
100 pub fn new(data_store: Arc<dyn DataStore>, record_store: Arc<dyn RecordStore>) -> Self {
101 Self {
102 data_store,
103 record_store,
104 }
105 }
106
107 pub async fn process_message(
108 &self,
109 target: &Did,
110 msg: Message,
111 ) -> Result<Option<Reply>, StatusCode> {
112 let validation = match handlers::validation::validate_message(&msg).await {
113 Ok(a) => a,
114 Err(e) => {
115 debug!("Failed to validate message: {:?}", e);
116 return Err(StatusCode::BAD_REQUEST);
117 }
118 };
119
120 let ctx = ProcessContext {
121 rs: self.record_store.as_ref(),
122 ds: self.data_store.as_ref(),
123 validation,
124 target,
125 msg,
126 };
127
128 let res = match &ctx.msg.descriptor {
129 Descriptor::ProtocolsConfigure(_) => {
130 handlers::protocols::configure::handle(ctx).await?;
131 None
132 }
133 Descriptor::ProtocolsQuery(_) => handlers::protocols::query::handle(ctx)
134 .await
135 .map(|v| Some(Reply::ProtocolsQuery(v)))?,
136 Descriptor::RecordsDelete(_) => {
137 handlers::records::delete::handle(ctx).await?;
138 None
139 }
140 Descriptor::RecordsQuery(_) => handlers::records::query::handle(ctx)
141 .await
142 .map(|v| Some(Reply::RecordsQuery(v)))?,
143 Descriptor::RecordsRead(_) => handlers::records::read::handle(ctx)
144 .await
145 .map(|v| Some(Reply::RecordsRead(Box::new(v))))?,
146 Descriptor::RecordsSync(_) => handlers::records::sync::handle(ctx)
147 .await
148 .map(|v| Some(Reply::RecordsSync(Box::new(v))))?,
149 Descriptor::RecordsWrite(_) => {
150 handlers::records::write::handle(ctx).await?;
151 None
152 }
153 };
154
155 Ok(res)
156 }
157}