use std::fmt;
use fhir_types::r4::patient::Patient;
use secrecy::SecretString;
use url::Url;
use crate::outcome::IssueType;
use ihe_atna::redact::REDACTED;
#[derive(Debug, Clone)]
pub struct SearchResult {
total: u32,
patients: Vec<MatchedPatient>,
warnings: Vec<IssueType>,
next: Option<Page>,
}
impl SearchResult {
pub(super) fn new(
total: u32,
patients: Vec<MatchedPatient>,
warnings: Vec<IssueType>,
next: Option<Page>,
) -> Self {
Self {
total,
patients,
warnings,
next,
}
}
#[must_use]
pub fn total(&self) -> u32 {
self.total
}
#[must_use]
pub fn patients(&self) -> &[MatchedPatient] {
&self.patients
}
#[must_use]
pub fn into_patients(self) -> Vec<MatchedPatient> {
self.patients
}
#[must_use]
pub fn warnings(&self) -> &[IssueType] {
&self.warnings
}
#[must_use]
pub fn next(&self) -> Option<&Page> {
self.next.as_ref()
}
}
#[derive(Clone)]
pub struct MatchedPatient {
full_url: SecretString,
patient: Box<Patient>,
score: Option<f64>,
grade: Option<MatchGrade>,
}
impl MatchedPatient {
pub(super) fn new(
full_url: SecretString,
patient: Box<Patient>,
score: Option<f64>,
grade: Option<MatchGrade>,
) -> Self {
Self {
full_url,
patient,
score,
grade,
}
}
#[must_use]
pub fn full_url(&self) -> &SecretString {
&self.full_url
}
#[must_use]
pub fn patient(&self) -> &Patient {
&self.patient
}
#[must_use]
pub fn score(&self) -> Option<f64> {
self.score
}
#[must_use]
pub fn grade(&self) -> Option<MatchGrade> {
self.grade
}
}
impl fmt::Debug for MatchedPatient {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MatchedPatient")
.field("full_url", &REDACTED)
.field("patient", &REDACTED)
.field("score", &self.score)
.field("grade", &self.grade)
.finish()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum MatchGrade {
Certain,
Probable,
Possible,
CertainlyNot,
}
impl MatchGrade {
pub(super) const EXTENSION: &str = "http://hl7.org/fhir/StructureDefinition/match-grade";
pub(super) fn from_code(code: &str) -> Option<Self> {
match code {
"certain" => Some(Self::Certain),
"probable" => Some(Self::Probable),
"possible" => Some(Self::Possible),
"certainly-not" => Some(Self::CertainlyNot),
_ => None,
}
}
}
#[derive(Clone)]
pub struct Page(Url);
impl Page {
pub(super) fn new(url: Url) -> Self {
Self(url)
}
pub(super) fn url(&self) -> &Url {
&self.0
}
}
impl fmt::Debug for Page {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Page({REDACTED})")
}
}
#[derive(Debug, Clone)]
pub struct MatchResult {
patients: Vec<MatchedPatient>,
warnings: Vec<IssueType>,
}
impl MatchResult {
pub(super) fn new(patients: Vec<MatchedPatient>, warnings: Vec<IssueType>) -> Self {
Self { patients, warnings }
}
#[must_use]
pub fn patients(&self) -> &[MatchedPatient] {
&self.patients
}
#[must_use]
pub fn into_patients(self) -> Vec<MatchedPatient> {
self.patients
}
#[must_use]
pub fn warnings(&self) -> &[IssueType] {
&self.warnings
}
}