aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/api/store.rs58
1 files changed, 22 insertions, 36 deletions
diff --git a/src/api/store.rs b/src/api/store.rs
index bc43824..a74d968 100644
--- a/src/api/store.rs
+++ b/src/api/store.rs
@@ -59,36 +59,7 @@ pub(crate) async fn get_store_root(
headers: HeaderMap,
Query(query): Query<ReadQuery>,
) -> Result<Response, StatusCode> {
- if query.shallow {
- return shallow(&state, Vec::new(), true, &query).await;
- }
- let accept = headers.get(ACCEPT).cloned();
- let want_conflicts = query.conflicts;
-
- let (response, source, heads) = state
- .render_read(
- true,
- query.heads,
- move |doc| {
- if want_conflicts {
- store::read_path_with_conflicts(doc, &Vec::new())
- .map(|found| found.map(|(value, conflicts)| (value, Some(conflicts))))
- } else {
- store::read_path(doc, &Vec::new()).map(|found| found.map(|value| (value, None)))
- }
- },
- move |result| {
- let (value, conflicts) = result
- .map_err(|e| store_status(e, "Failed to read store path"))?
- .unwrap_or_else(|| (JsonValue::Object(Default::default()), Some(Vec::new())));
- match conflicts {
- Some(conflicts) => conflicts_response(value, conflicts),
- None => response_for_value(&value, accept.as_ref()),
- }
- },
- )
- .await?;
- mark_source(response, source, heads)
+ read(&state, Vec::new(), &headers, &query).await
}
/// `GET /store/{key}`.
@@ -103,16 +74,28 @@ pub(crate) async fn get_store_entry(
if let Some(redirect) = to_positive(&state, &path, false, raw_query.as_deref()).await? {
return Ok(redirect);
}
+ read(&state, path, &headers, &query).await
+}
+
+/// A read of `path` as `query` asks (the empty path: the whole store). The root is read
+/// while not ready too (`render_read`'s `unready_live`), and is never missing: an empty
+/// store is an empty map.
+async fn read(
+ state: &AppState,
+ path: Vec<String>,
+ headers: &HeaderMap,
+ query: &ReadQuery,
+) -> Result<Response, StatusCode> {
+ let root = path.is_empty();
if query.shallow {
- return shallow(&state, path, false, &query).await;
+ return shallow(state, path, root, query).await;
}
-
let accept = headers.get(ACCEPT).cloned();
let want_conflicts = query.conflicts;
let (response, source, heads) = state
.render_read(
- false,
+ root,
query.heads,
move |doc| {
if want_conflicts {
@@ -123,9 +106,12 @@ pub(crate) async fn get_store_entry(
}
},
move |result| {
- let (value, conflicts) = result
- .map_err(|e| store_status(e, "Failed to read store path"))?
- .ok_or(StatusCode::NOT_FOUND)?;
+ let found = result.map_err(|e| store_status(e, "Failed to read store path"))?;
+ let (value, conflicts) = match found {
+ Some(found) => found,
+ None if root => (JsonValue::Object(Default::default()), Some(Vec::new())),
+ None => return Err(StatusCode::NOT_FOUND),
+ };
match conflicts {
Some(conflicts) => conflicts_response(value, conflicts),
None => response_for_value(&value, accept.as_ref()),