-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add AttributeFraming overlay and related structures to enhance …
…attribute management
1 parent
cab0634
commit 0321796
Showing
4 changed files
with
188 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
159 changes: 159 additions & 0 deletions
159
semantics/oca-bundle/src/state/oca/overlay/attribute_framing.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
use crate::state::{attribute::Attribute, oca::Overlay}; | ||
use isolang::Language; | ||
use oca_ast_semantics::ast::OverlayType; | ||
use said::derivation::HashFunctionCode; | ||
use said::{sad::SerializationFormats, sad::SAD}; | ||
use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer}; | ||
use std::any::Any; | ||
use std::collections::HashMap; | ||
|
||
pub type Framing = HashMap<String, FramingScope>; | ||
|
||
#[derive(Serialize, Deserialize, Debug, Clone)] | ||
pub struct FramingScope { | ||
pub predicate_id: String, | ||
pub framing_justification: String, | ||
} | ||
|
||
pub trait Framings { | ||
fn set_framing(&mut self, id: String, framing: Framing); | ||
} | ||
|
||
impl Framings for Attribute { | ||
fn set_framing(&mut self, id: String, framing: Framing) { | ||
match self.framings { | ||
Some(ref mut framings) => { | ||
if let Some(f) = framings.get_mut(&id) { | ||
f.extend(framing); | ||
} else { | ||
framings.insert(id, framing); | ||
} | ||
} | ||
None => { | ||
let mut framings = HashMap::new(); | ||
framings.insert(id, framing); | ||
self.framings = Some(framings); | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn serialize_framing<S>( | ||
attributes: &HashMap<String, Framing>, | ||
s: S, | ||
) -> Result<S::Ok, S::Error> | ||
where | ||
S: Serializer, | ||
{ | ||
use std::collections::BTreeMap; | ||
|
||
let mut ser = s.serialize_map(Some(attributes.len()))?; | ||
let sorted_attributes: BTreeMap<_, _> = attributes.iter().collect(); | ||
for (k, v) in sorted_attributes { | ||
let sorted_framings: BTreeMap<_, _> = v.iter().collect(); | ||
ser.serialize_entry(k, &sorted_framings)?; | ||
} | ||
ser.end() | ||
} | ||
|
||
#[derive(SAD, Serialize, Deserialize, Debug, Clone)] | ||
pub struct AttributeFramingOverlay { | ||
#[said] | ||
#[serde(rename = "d")] | ||
said: Option<said::SelfAddressingIdentifier>, | ||
capture_base: Option<said::SelfAddressingIdentifier>, | ||
#[serde(rename = "type")] | ||
overlay_type: OverlayType, | ||
#[serde(rename = "framing_metadata")] | ||
pub metadata: HashMap<String, String>, | ||
#[serde(serialize_with = "serialize_framing")] | ||
pub attribute_framing: HashMap<String, Framing>, | ||
} | ||
|
||
impl Overlay for AttributeFramingOverlay { | ||
fn as_any(&self) -> &dyn Any { | ||
self | ||
} | ||
fn capture_base(&self) -> &Option<said::SelfAddressingIdentifier> { | ||
&self.capture_base | ||
} | ||
fn set_capture_base(&mut self, said: &said::SelfAddressingIdentifier) { | ||
self.capture_base = Some(said.clone()); | ||
} | ||
fn overlay_type(&self) -> &OverlayType { | ||
&self.overlay_type | ||
} | ||
fn said(&self) -> &Option<said::SelfAddressingIdentifier> { | ||
&self.said | ||
} | ||
fn language(&self) -> Option<&Language> { | ||
None | ||
} | ||
fn attributes(&self) -> Vec<&String> { | ||
self.attribute_framing.keys().collect::<Vec<&String>>() | ||
} | ||
/// Add an attribute to the Label Overlay | ||
/// TODO add assignment of attribute to category | ||
fn add(&mut self, attribute: &Attribute) { | ||
if let Some(id) = self.metadata.get("frame_id") { | ||
if let Some(framing) = &attribute.framings { | ||
if let Some(value) = framing.get(id) { | ||
self.attribute_framing | ||
.insert(attribute.name.clone(), value.clone()); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
impl AttributeFramingOverlay { | ||
pub fn new(id: String) -> Self { | ||
let mut metadata = HashMap::new(); | ||
metadata.insert("frame_id".to_string(), id); | ||
Self { | ||
capture_base: None, | ||
said: None, | ||
overlay_type: OverlayType::AttributeFraming, | ||
metadata, | ||
attribute_framing: HashMap::new(), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
|
||
#[test] | ||
fn create_attribute_framing_overlay() { | ||
let mut overlay = AttributeFramingOverlay::new("frame_id".to_string()); | ||
let mut loc1 = HashMap::new(); | ||
loc1.insert( | ||
"http://loc.1".to_string(), | ||
FramingScope { | ||
predicate_id: "skos:exactMatch".to_string(), | ||
framing_justification: "semapv:ManualMappingCuration" | ||
.to_string(), | ||
}, | ||
); | ||
let mut loc2 = HashMap::new(); | ||
loc2.insert( | ||
"http://loc.2".to_string(), | ||
FramingScope { | ||
predicate_id: "skos:exactMatch".to_string(), | ||
framing_justification: "semapv:ManualMappingCuration" | ||
.to_string(), | ||
}, | ||
); | ||
let attr = cascade! { | ||
Attribute::new("attr1".to_string()); | ||
..set_framing("frame_id".to_string(), loc1); | ||
..set_framing("frame_id".to_string(), loc2); | ||
}; | ||
// even that attribute has 2 lagnuage only one attribute should be added to the overlay according to it's language | ||
overlay.add(&attr); | ||
|
||
assert_eq!(overlay.overlay_type, OverlayType::AttributeFraming); | ||
assert_eq!(overlay.attribute_framing.len(), 1); | ||
} | ||
} |