use crate::{
lsp_ext::request::{
AssociatedSchemaParams, AssociatedSchemaResponse, ListSchemasParams, ListSchemasResponse,
SchemaInfo,
},
world::World,
};
use indexmap::IndexMap;
use jsona_util::{environment::Environment, schema::associations::priority};
use lsp_async_stub::{rpc::Error, Context, Params};
use serde_json::Value;
use url::Url;
#[tracing::instrument(skip_all)]
pub async fn list_schemas<E: Environment>(
context: Context<World<E>>,
params: Params<ListSchemasParams>,
) -> Result<ListSchemasResponse, Error> {
let p = params.required()?;
let workspaces = context.workspaces.read().await;
let document_uri = p.document_uri;
let ws = workspaces.by_document(&document_uri);
let associations = ws.schemas.associations().read();
let mut map: IndexMap<Url, Value> = associations
.iter()
.filter(|(_, s)| matches!(s.priority, priority::STORE))
.map(|(_, s)| (s.url.clone(), s.meta.clone()))
.collect();
for (_, s) in associations
.iter()
.filter(|(_, s)| s.priority != priority::STORE)
{
if map.contains_key(&s.url) {
continue;
}
map.insert(s.url.clone(), s.meta.clone());
}
Ok(ListSchemasResponse {
schemas: map
.into_iter()
.map(|(url, meta)| SchemaInfo { url, meta })
.collect(),
})
}
#[tracing::instrument(skip_all)]
pub async fn associated_schema<E: Environment>(
context: Context<World<E>>,
params: Params<AssociatedSchemaParams>,
) -> Result<AssociatedSchemaResponse, Error> {
let p = params.required()?;
let workspaces = context.workspaces.read().await;
let document_uri = &p.document_uri;
let ws = workspaces.by_document(document_uri);
let association = ws.schemas.associations().query_for(document_uri);
Ok(AssociatedSchemaResponse {
schema: association.map(|s| SchemaInfo {
url: s.url.clone(),
meta: s.meta.clone(),
}),
})
}