#[rustfmt::skip] mod generated;
pub use generated::*;
use super::types::{FieldExtension, Identifier};
pub trait IdentifiableResource {
	fn identifier(&self) -> &Vec<Option<Identifier>>;
	fn identifier_mut(&mut self) -> &mut Vec<Option<Identifier>>;
	fn set_identifier(&mut self, value: Vec<Option<Identifier>>);
	fn identifier_ext(&self) -> &Vec<Option<FieldExtension>>;
	fn identifier_ext_mut(&mut self) -> &mut Vec<Option<FieldExtension>>;
	fn set_identifier_ext(&mut self, value: Vec<Option<FieldExtension>>);
	fn place_identifier(&mut self, identifier: Identifier) -> bool {
		if let Some(ident) = self.identifier_mut().iter_mut().flatten().find(|ident| {
			(ident.system.is_some() && ident.system == identifier.system)
				|| (ident.r#type.is_some() && ident.r#type == identifier.r#type)
		}) {
			*ident = identifier;
			false
		} else {
			self.identifier_mut().push(Some(identifier));
			if !self.identifier_ext_mut().is_empty()
				&& self.identifier_mut().len() == self.identifier_ext_mut().len() + 1
			{
				self.identifier_ext_mut().push(None);
			}
			true
		}
	}
	fn identifier_with_system(&self, system: &str) -> Option<&String> {
		self.identifier()
			.iter()
			.flatten()
			.filter(|ident| ident.system.as_ref().map_or(false, |sys| sys == system))
			.find_map(|ident| ident.value.as_ref())
	}
	fn identifiers_with_system(&self, system: &str) -> Vec<&Identifier> {
		self.identifier()
			.iter()
			.flatten()
			.filter(|ident| ident.system.as_ref().map_or(false, |sys| sys == system))
			.collect()
	}
	fn identifier_with_type(&self, type_system: &str, type_code: &str) -> Option<&String> {
		self.identifier()
			.iter()
			.flatten()
			.filter(|ident| {
				ident.r#type.as_ref().map_or(false, |ty| {
					ty.coding.iter().flatten().any(|coding| {
						coding.system.as_deref() == Some(type_system)
							&& coding.code.as_deref() == Some(type_code)
					})
				})
			})
			.find_map(|ident| ident.value.as_ref())
	}
	fn identifiers_with_type(&self, type_system: &str, type_code: &str) -> Vec<&Identifier> {
		self.identifier()
			.iter()
			.flatten()
			.filter(|ident| {
				ident.r#type.as_ref().map_or(false, |ty| {
					ty.coding.iter().flatten().any(|coding| {
						coding.system.as_deref() == Some(type_system)
							&& coding.code.as_deref() == Some(type_code)
					})
				})
			})
			.collect()
	}
}
macro_rules! impl_identifiable_resource {
	([$($resource:ident),*$(,)?]) => {
		$(impl_identifiable_resource!($resource);)*
		impl Resource {
			#[must_use]
			#[inline]
			pub fn as_identifiable_resource(&self) -> Option<&dyn IdentifiableResource> {
				match self {
					$(
						Self::$resource(r) => Some(r),
					)*
					_ => None,
				}
			}
			#[must_use]
			#[inline]
			pub fn as_identifiable_resource_mut(&mut self) -> Option<&mut dyn IdentifiableResource> {
				match self {
					$(
						Self::$resource(r) => Some(r),
					)*
					_ => None,
				}
			}
		}
	};
	($resource:ident) => {
		impl IdentifiableResource for $resource {
			#[inline]
			fn identifier(&self) -> &Vec<Option<Identifier>> {
				&self.identifier
			}
			#[inline]
			fn identifier_mut(&mut self) -> &mut Vec<Option<Identifier>> {
				&mut self.identifier
			}
			#[inline]
			fn set_identifier(&mut self, value: Vec<Option<Identifier>>) {
				self.identifier = value;
			}
			#[inline]
			fn identifier_ext(&self) -> &Vec<Option<FieldExtension>> {
				&self.identifier_ext
			}
			#[inline]
			fn identifier_ext_mut(&mut self) -> &mut Vec<Option<FieldExtension>> {
				&mut self.identifier_ext
			}
			#[inline]
			fn set_identifier_ext(&mut self, value: Vec<Option<FieldExtension>>) {
				self.identifier_ext = value;
			}
		}
	};
}
impl_identifiable_resource!([
	Account,
	ActivityDefinition,
	ActorDefinition,
	AdministrableProductDefinition,
	AdverseEvent,
	AllergyIntolerance,
	Appointment,
	AppointmentResponse,
	ArtifactAssessment,
	Basic,
	BiologicallyDerivedProduct,
	BiologicallyDerivedProductDispense,
	BodyStructure,
	CapabilityStatement,
	CarePlan,
	CareTeam,
	ChargeItem,
	ChargeItemDefinition,
	Citation,
	Claim,
	ClaimResponse,
	ClinicalImpression,
	ClinicalUseDefinition,
	CodeSystem,
	Communication,
	CommunicationRequest,
	Composition,
	ConceptMap,
	Condition,
	ConditionDefinition,
	Consent,
	Contract,
	Coverage,
	CoverageEligibilityRequest,
	CoverageEligibilityResponse,
	DetectedIssue,
	Device,
	DeviceAssociation,
	DeviceDefinition,
	DeviceDispense,
	DeviceMetric,
	DeviceRequest,
	DeviceUsage,
	DiagnosticReport,
	DocumentReference,
	Encounter,
	EncounterHistory,
	Endpoint,
	EnrollmentRequest,
	EnrollmentResponse,
	EpisodeOfCare,
	EventDefinition,
	Evidence,
	EvidenceReport,
	EvidenceVariable,
	ExampleScenario,
	ExplanationOfBenefit,
	FamilyMemberHistory,
	Flag,
	FormularyItem,
	GenomicStudy,
	Goal,
	GraphDefinition,
	Group,
	GuidanceResponse,
	HealthcareService,
	ImagingSelection,
	ImagingStudy,
	Immunization,
	ImmunizationEvaluation,
	ImmunizationRecommendation,
	ImplementationGuide,
	InsurancePlan,
	InventoryItem,
	InventoryReport,
	Invoice,
	Library,
	List,
	Location,
	ManufacturedItemDefinition,
	Measure,
	MeasureReport,
	Medication,
	MedicationAdministration,
	MedicationDispense,
	MedicationKnowledge,
	MedicationRequest,
	MedicationStatement,
	MedicinalProductDefinition,
	MessageDefinition,
	MolecularSequence,
	NamingSystem,
	NutritionIntake,
	NutritionOrder,
	Observation,
	OperationDefinition,
	Organization,
	OrganizationAffiliation,
	PackagedProductDefinition,
	Patient,
	PaymentNotice,
	PaymentReconciliation,
	Person,
	PlanDefinition,
	Practitioner,
	PractitionerRole,
	Procedure,
	Questionnaire,
	QuestionnaireResponse,
	RegulatedAuthorization,
	RelatedPerson,
	RequestOrchestration,
	Requirements,
	ResearchStudy,
	ResearchSubject,
	RiskAssessment,
	Schedule,
	SearchParameter,
	ServiceRequest,
	Slot,
	Specimen,
	StructureDefinition,
	StructureMap,
	Subscription,
	SubscriptionTopic,
	Substance,
	SubstanceDefinition,
	SupplyDelivery,
	SupplyRequest,
	Task,
	TerminologyCapabilities,
	TestPlan,
	TestScript,
	Transport,
	ValueSet,
	VisionPrescription
]);