.
This commit is contained in:
Generated
+10
-4
@@ -328,6 +328,12 @@ version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b25655df2c3cdd83c5e5b293b88acd880332b2ddadd7c30ac43144fdc0033da9"
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.72.1"
|
||||
@@ -1622,7 +1628,7 @@ version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
@@ -2099,7 +2105,7 @@ name = "ldp"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64",
|
||||
"base64 0.23.0",
|
||||
"bytes",
|
||||
"futures",
|
||||
"http",
|
||||
@@ -3468,7 +3474,7 @@ version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@@ -4104,7 +4110,7 @@ checksum = "edde6a10743fff00a4e1a8c9ef020bf5f3cbad301b7d2d39f2b07f123c4eac07"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"arc-swap",
|
||||
"base64",
|
||||
"base64 0.22.1",
|
||||
"bitpacking",
|
||||
"bon",
|
||||
"byteorder",
|
||||
|
||||
+33
-11
@@ -18,7 +18,7 @@ use ldp::traverse::Traverse;
|
||||
use ldp::{RdfSource, RdfSourceUpdateResponse, ResourceRequestBuilder, SerializationOptions};
|
||||
use oxigraph::io::RdfFormat;
|
||||
use oxigraph::model::vocab::{rdf, rdfs};
|
||||
use oxigraph::model::{BaseDirection, Dataset, NamedNode, Quad, Term};
|
||||
use oxigraph::model::{BaseDirection, Dataset, NamedNode, NamedOrBlankNode, Quad, Term};
|
||||
use tracing::{debug_span, error, field, trace};
|
||||
use crate::navigator::Navigator;
|
||||
use crate::rdf::curie::CurieHelper;
|
||||
@@ -56,6 +56,7 @@ pub(crate) enum Message {
|
||||
SearchResultClicked(NamedNode),
|
||||
DatatypeUpdated(QuadKey, Option<String>),
|
||||
LanguageUpdated(QuadKey, Option<String>),
|
||||
SubjectUpdated(QuadKey, String),
|
||||
PredicateUpdated(QuadKey, String),
|
||||
ObjectUpdated(QuadKey, String),
|
||||
DirectionToggled(QuadKey, BaseDirection),
|
||||
@@ -129,7 +130,7 @@ impl Publisher {
|
||||
let mut abbreviated_datatypes = ontology
|
||||
.datatypes()
|
||||
.into_iter()
|
||||
.map(|node| curie_helper.abbreviate(node.as_str())
|
||||
.map(|node| curie_helper.abbreviate(None, node.as_str())
|
||||
.unwrap_or(node.as_str().to_string())
|
||||
).collect::<Vec<_>>();
|
||||
abbreviated_datatypes.sort();
|
||||
@@ -238,7 +239,7 @@ impl Publisher {
|
||||
Schema::iri_field() => individual.as_str(),
|
||||
);
|
||||
|
||||
if let Some(curie) = curie_helper.abbreviate(individual.as_str()) {
|
||||
if let Some(curie) = curie_helper.abbreviate(None, individual.as_str()) {
|
||||
document.add_text(Schema::curie_field(), curie);
|
||||
}
|
||||
|
||||
@@ -340,7 +341,7 @@ impl Publisher {
|
||||
let term = TermHelper::new(&quad.object);
|
||||
let datatype = term
|
||||
.datatype()
|
||||
.map(|datatype| self.curie_helper.abbreviate(datatype.as_str())
|
||||
.map(|datatype| self.curie_helper.abbreviate(None, datatype.as_str())
|
||||
.unwrap_or(datatype.as_str().to_string()));
|
||||
|
||||
let datatype_state = combo_box::State::with_selection(
|
||||
@@ -454,7 +455,7 @@ impl Publisher {
|
||||
Message::DatatypeUpdated(key, Some(maybe_prefixed_iri)) => {
|
||||
let node = self
|
||||
.curie_helper
|
||||
.expand(&maybe_prefixed_iri)
|
||||
.expand(None, &maybe_prefixed_iri)
|
||||
.unwrap_or(maybe_prefixed_iri);
|
||||
|
||||
if let Some(quad) = self.document.dataset_mut().quads.get_mut(key) {
|
||||
@@ -484,6 +485,12 @@ impl Publisher {
|
||||
self.modified = true;
|
||||
}
|
||||
}
|
||||
Message::SubjectUpdated(key, value) => {
|
||||
if let Some(quad) = self.document.dataset_mut().quads.get_mut(key) {
|
||||
quad.subject = NamedOrBlankNode::NamedNode(NamedNode::new_unchecked(value));
|
||||
self.modified = true;
|
||||
}
|
||||
}
|
||||
Message::PredicateUpdated(key, value) => {
|
||||
if let Some(quad) = self.document.dataset_mut().quads.get_mut(key) {
|
||||
quad.predicate = NamedNode::new_unchecked(value);
|
||||
@@ -627,7 +634,21 @@ impl Publisher {
|
||||
container(space()).width(BUTTON_WIDTH)
|
||||
};
|
||||
|
||||
let predicate_input_base = iri_input(&self.curie_helper, "Predicate", triple.predicate.as_str());
|
||||
let base = self.document.origin().as_str();
|
||||
|
||||
let subject = match &triple.subject {
|
||||
NamedOrBlankNode::NamedNode(subject) => subject.as_str(),
|
||||
_ => "",
|
||||
};
|
||||
|
||||
let subject_input_base = iri_input(&self.curie_helper, "Subject", Some(&base), subject);
|
||||
let subject_input = if self.ontology.is_read_only(triple.as_ref()) {
|
||||
subject_input_base
|
||||
} else {
|
||||
subject_input_base.on_input(move |value| Message::SubjectUpdated(key, value))
|
||||
};
|
||||
|
||||
let predicate_input_base = iri_input(&self.curie_helper, "Predicate", Some(&base), triple.predicate.as_str());
|
||||
let predicate_input = if self.ontology.is_read_only(triple.as_ref()) {
|
||||
predicate_input_base
|
||||
} else {
|
||||
@@ -659,7 +680,7 @@ impl Publisher {
|
||||
})
|
||||
.unwrap_or(Horizontal::Left);
|
||||
|
||||
let object_input_base = iri_input(&self.curie_helper, "Object", value.as_str())
|
||||
let object_input_base = iri_input(&self.curie_helper, "Object", Some(&base), value.as_str())
|
||||
.on_shift_click(Message::NavigateToObject(key));
|
||||
let object_input = if self.ontology.is_read_only(triple.as_ref()) {
|
||||
object_input_base
|
||||
@@ -670,7 +691,7 @@ impl Publisher {
|
||||
};
|
||||
|
||||
let selected_datatype = term.datatype()
|
||||
.and_then(|node| self.curie_helper.abbreviate(node.as_str()));
|
||||
.and_then(|node| self.curie_helper.abbreviate(None, node.as_str()));
|
||||
|
||||
let datatype_selector: Element<Message> = if state.read_only {
|
||||
selected_datatype.map(text).into()
|
||||
@@ -720,6 +741,7 @@ impl Publisher {
|
||||
|
||||
let row = row![
|
||||
button_area,
|
||||
subject_input,
|
||||
predicate_input,
|
||||
predicate_label,
|
||||
object_input,
|
||||
@@ -740,7 +762,7 @@ impl Publisher {
|
||||
entities: impl IntoIterator<Item = LabeledIri>,
|
||||
) -> Element<'_, Message> {
|
||||
let buttons = entities.into_iter().map(|entity| {
|
||||
let abbreviation = self.curie_helper.abbreviate(entity.iri.as_str())
|
||||
let abbreviation = self.curie_helper.abbreviate(None, entity.iri.as_str())
|
||||
.unwrap_or_else(|| entity.iri.as_str().to_string());
|
||||
|
||||
let label = format!("{} ({})", entity.label, abbreviation);
|
||||
@@ -775,7 +797,7 @@ impl Publisher {
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or_default();
|
||||
|
||||
let abbreviated_iri = self.curie_helper.abbreviate(iri)
|
||||
let abbreviated_iri = self.curie_helper.abbreviate(None, iri)
|
||||
.unwrap_or_else(|| iri.to_string());
|
||||
|
||||
button(text(abbreviated_iri).wrapping(Wrapping::Word))
|
||||
@@ -830,7 +852,7 @@ impl Publisher {
|
||||
|
||||
let reindex_ontology_button = button("Rebuild index").on_press(Message::RebuildIndex);
|
||||
|
||||
let address_input = iri_input(&self.curie_helper, "URL", &self.url_input)
|
||||
let address_input = iri_input(&self.curie_helper, "URL", None, &self.url_input)
|
||||
.on_input(Message::URLInputChanged)
|
||||
.on_submit(Message::URLInputSubmitted)
|
||||
.on_control_click(Message::OpenQueryWindow(SearchResultClickAction::URLInput));
|
||||
|
||||
@@ -12,7 +12,11 @@ impl CurieHelper {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn abbreviate(&self, iri: &str) -> Option<String> {
|
||||
pub fn abbreviate(&self, base: Option<&str>, iri: &str) -> Option<String> {
|
||||
if let Some(base) = base && let Some(local_name) = iri.strip_prefix(base) {
|
||||
return Some(format!(":{local_name}"));
|
||||
}
|
||||
|
||||
for (name, base) in &self.prefixes {
|
||||
if let Some(local_name) = iri.strip_prefix(base) {
|
||||
return Some(format!("{name}:{local_name}"));
|
||||
@@ -21,10 +25,15 @@ impl CurieHelper {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn expand(&self, abbreviated_iri: &str) -> Option<String> {
|
||||
pub fn expand(&self, base: Option<&str>, abbreviated_iri: &str) -> Option<String> {
|
||||
let (prefix, name) = abbreviated_iri.split_once(':')?;
|
||||
self.prefixes
|
||||
.get(prefix)
|
||||
.map(|base| format!("{base}{name}"))
|
||||
|
||||
if prefix == "" && let Some(base) = base {
|
||||
Some(format!("{base}{name}"))
|
||||
} else {
|
||||
self.prefixes
|
||||
.get(prefix)
|
||||
.map(|base| format!("{base}{name}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,8 @@ static PREFIXES: LazyLock<BTreeMap<String, String>> = LazyLock::new(|| {
|
||||
"ebucore",
|
||||
"http://www.ebu.ch/metadata/ontologies/ebucore/ebucore#",
|
||||
),
|
||||
("prov", "http://www.w3.org/ns/prov#"),
|
||||
("locid", "http://id.loc.gov/vocabulary/identifiers/"),
|
||||
("premis", "http://www.loc.gov/premis/rdf/v1#"),
|
||||
("premis3", "http://www.loc.gov/premis/rdf/v3/"),
|
||||
("dcterms", "http://purl.org/dc/terms/"),
|
||||
|
||||
@@ -20,6 +20,7 @@ where
|
||||
Renderer: text::Renderer,
|
||||
{
|
||||
curie_helper: &'a CurieHelper,
|
||||
base: Option<String>,
|
||||
on_control_click: Option<Message>,
|
||||
on_shift_click: Option<Message>,
|
||||
text_input: widget::TextInput<'a, Message, Theme, Renderer>,
|
||||
@@ -31,11 +32,12 @@ where
|
||||
Theme: Catalog,
|
||||
Renderer: text::Renderer,
|
||||
{
|
||||
pub fn new(curie_helper: &'a CurieHelper, placeholder: &str, iri: &str) -> Self {
|
||||
let display_value = curie_helper.abbreviate(iri).unwrap_or_else(|| iri.to_string());
|
||||
pub fn new(curie_helper: &'a CurieHelper, placeholder: &str, base: Option<&str>, iri: &str) -> Self {
|
||||
let display_value = curie_helper.abbreviate(base, iri).unwrap_or_else(|| iri.to_string());
|
||||
let text_input = widget::TextInput::new(placeholder, &display_value);
|
||||
Self {
|
||||
curie_helper,
|
||||
base: base.map(String::from),
|
||||
on_control_click: None,
|
||||
on_shift_click: None,
|
||||
text_input,
|
||||
@@ -62,8 +64,9 @@ where
|
||||
|
||||
#[must_use]
|
||||
pub fn on_input(mut self, on_input: impl Fn(String) -> Message + 'a) -> Self {
|
||||
let base_clone = self.base.clone();
|
||||
let wrapped = move |value: String| {
|
||||
let expanded_value = self.curie_helper.expand(&value);
|
||||
let expanded_value = self.curie_helper.expand(base_clone.as_deref(), &value);
|
||||
on_input(expanded_value.unwrap_or_else(|| value))
|
||||
};
|
||||
|
||||
@@ -90,13 +93,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iri_input<'a, Message, Theme, Renderer>(curie_helper: &'a CurieHelper, placeholder: &str, iri: &str) -> IriInput<'a, Message, Theme, Renderer>
|
||||
pub fn iri_input<'a, Message, Theme, Renderer>(curie_helper: &'a CurieHelper, placeholder: &str, base: Option<&str>, iri: &str) -> IriInput<'a, Message, Theme, Renderer>
|
||||
where
|
||||
Message: Clone,
|
||||
Theme: Catalog,
|
||||
Renderer: text::Renderer,
|
||||
{
|
||||
IriInput::new(curie_helper, placeholder, iri)
|
||||
IriInput::new(curie_helper, placeholder, base, iri)
|
||||
}
|
||||
|
||||
impl <Message, Theme, Renderer> Widget<Message, Theme, Renderer> for IriInput<'_, Message, Theme, Renderer>
|
||||
@@ -160,7 +163,7 @@ where
|
||||
|
||||
let clipboard = shell.clipboard_mut();
|
||||
if let Some(Content::Text(content)) = &clipboard.write {
|
||||
if let Some(expanded) = self.curie_helper.expand(&content) {
|
||||
if let Some(expanded) = self.curie_helper.expand(self.base.as_deref(), &content) {
|
||||
clipboard.write = Some(Content::Text(expanded));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user