use serde::{Deserialize, Serialize};
use crate::{
event_label::SendMsg, identifier::Identifier, predicate::PredicateType, thread::ThreadId,
};
use std::fmt::{Debug, Display};
#[derive(Clone, Debug, PartialEq)]
pub(crate) struct WakeMsg;
#[derive(Clone, Copy, Default, Debug, Hash, Serialize, Deserialize, PartialEq, Eq)]
pub enum CommunicationModel {
NoOrder,
#[default]
LocalOrder,
CausalOrder,
TotalOrder,
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub(crate) struct Loc(Box<dyn Identifier>);
impl Loc {
pub(crate) fn new<T: crate::identifier::Identifier>(id: T) -> Self {
Loc(Box::new(id))
}
}
impl Display for Loc {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct RecvLoc {
#[serde(skip)]
locs: Option<Vec<Loc>>,
tag: Option<PredicateType>,
}
impl RecvLoc {
pub(crate) fn new(locs: Vec<&Loc>, tag: Option<PredicateType>) -> Self {
RecvLoc {
locs: Some(locs.into_iter().cloned().collect()),
tag,
}
}
pub(crate) fn locs(&self) -> &Vec<Loc> {
self.locs.as_ref().unwrap()
}
pub(crate) fn matches_tag(&self, send: &SendMsg) -> bool {
let send_loc = send.send_loc();
self.tag.is_none() || self.tag.as_ref().unwrap().0(send_loc.sender_tid, send_loc.tag.clone())
}
pub(crate) fn matches(&self, send: &SendMsg) -> bool {
self.matches_tag(send) && self.locs().iter().any(|rc| rc == send.loc())
}
pub(crate) fn get_matching_index(&self, send_loc: &SendLoc) -> usize {
self.locs()
.iter()
.position(|c| c == send_loc.loc())
.unwrap()
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub(crate) struct SendLoc {
#[serde(skip)]
loc: Option<Loc>,
pub(crate) sender_tid: ThreadId,
pub(crate) tag: Option<Vec<u32>>,
}
impl SendLoc {
#[allow(dead_code)]
pub(crate) fn new_empty(sender_tid: ThreadId) -> Self {
SendLoc {
loc: None,
sender_tid,
tag: None,
}
}
pub(crate) fn new(loc: &Loc, sender_tid: ThreadId, tag: Option<Vec<u32>>) -> Self {
SendLoc {
loc: Some(loc.clone()),
sender_tid,
tag,
}
}
pub(crate) fn loc(&self) -> &Loc {
self.loc.as_ref().unwrap()
}
}
impl Display for RecvLoc {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.locs)
}
}
impl Display for SendLoc {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.loc)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_match() {
let id1: Loc = Loc::new("foo".to_string());
let id2: Loc = Loc::new("bar".to_string());
let id3: Loc = Loc::new(42);
let id4: Loc = Loc::new(42);
assert!(id1 != id2);
assert!(id2 != id3);
assert!(id3 == id4);
}
#[test]
fn test_display() {
let id: Loc = Loc::new("foo".to_string());
assert_eq!(format!("{:}", id), "\"foo\"")
}
#[test]
fn test_debug() {
let id: Loc = Loc::new("foo".to_string());
assert_eq!(format!("{:?}", id), "Loc(\"foo\")")
}
#[test]
fn test_clone() {
let id1: Loc = Loc::new("foo".to_string());
let id2: Loc = Loc::new(42);
assert!(id1 == id1.clone());
assert!(id1.clone() != id2);
}
}