1use core::convert::Infallible;
4
5use bevy_ecs::prelude as ecs;
6
7use crate::transaction;
8use crate::universe::{self, Handle};
9
10#[cfg(doc)]
11use crate::universe::Universe;
12
13#[derive(Clone, Debug, Eq, Hash, PartialEq)]
19#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
20#[non_exhaustive]
21pub enum Tag {
22 Handle(Handle<TagDef>),
24 }
26
27#[expect(clippy::exhaustive_structs)]
34#[derive(Clone, Debug, Eq, Hash, PartialEq)]
35#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
36pub struct Be(pub Tag);
37
38#[expect(clippy::exhaustive_structs)]
40#[derive(Clone, Debug, Eq, Hash, PartialEq)]
41#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
42pub struct Is(pub Tag);
43
44impl universe::VisitHandles for Tag {
47 fn visit_handles(&self, visitor: &mut dyn universe::HandleVisitor) {
48 match self {
49 Tag::Handle(handle) => handle.visit_handles(visitor),
50 }
51 }
52}
53impl universe::VisitHandles for Be {
54 fn visit_handles(&self, visitor: &mut dyn universe::HandleVisitor) {
55 match self {
56 Be(tag) => tag.visit_handles(visitor),
57 }
58 }
59}
60impl universe::VisitHandles for Is {
61 fn visit_handles(&self, visitor: &mut dyn universe::HandleVisitor) {
62 match self {
63 Is(tag) => tag.visit_handles(visitor),
64 }
65 }
66}
67
68#[doc = include_str!("save/serde-warning.md")]
73#[expect(clippy::exhaustive_structs)]
74#[expect(clippy::module_name_repetitions, reason = "TODO: reconsider")]
75#[derive(Debug, bevy_ecs::component::Component)]
76#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
77pub struct TagDef;
78
79universe::impl_universe_member_for_single_component_type!(TagDef);
80
81impl universe::VisitHandles for TagDef {
82 fn visit_handles(&self, _: &mut dyn universe::HandleVisitor) {
83 let &TagDef = self;
84 }
86}
87
88impl transaction::Transactional for TagDef {
89 type Transaction = DefTransaction;
90}
91
92#[non_exhaustive]
96#[derive(Clone, Debug, Eq, PartialEq)]
97pub enum DefTransaction {}
98
99impl transaction::Merge for DefTransaction {
100 type MergeCheck = ();
101 type Conflict = Infallible;
102
103 fn check_merge(&self, _: &Self) -> Result<Self::MergeCheck, Self::Conflict> {
104 match *self {}
105 }
106
107 fn commit_merge(&mut self, _: Self, (): Self::MergeCheck) {
108 match *self {}
109 }
110}
111
112impl transaction::Transaction for DefTransaction {
113 type Target = TagDef;
114 type Context<'a> = universe::ReadTicket<'a>;
116 type CommitCheck = ();
117 type Output = transaction::NoOutput;
118 type Mismatch = Infallible;
119
120 fn check(
121 &self,
122 _: &Self::Target,
123 _: Self::Context<'_>,
124 ) -> Result<Self::CommitCheck, Self::Mismatch> {
125 match *self {}
126 }
127
128 fn commit(
129 self,
130 _: &mut Self::Target,
131 (): Self::CommitCheck,
132 _: &mut dyn FnMut(Self::Output),
133 ) -> Result<(), transaction::CommitError> {
134 match self {}
135 }
136}
137
138impl universe::TransactionOnEcs for DefTransaction {
139 type WriteQueryData = &'static mut Self::Target;
140
141 fn check(
142 &self,
143 target: &TagDef,
144 read_ticket: universe::ReadTicket<'_>,
145 ) -> Result<Self::CommitCheck, Self::Mismatch> {
146 transaction::Transaction::check(self, target, read_ticket)
147 }
148
149 fn commit(
150 self,
151 mut target: ecs::Mut<'_, TagDef>,
152 check: Self::CommitCheck,
153 ) -> Result<(), transaction::CommitError> {
154 transaction::Transaction::commit(self, &mut *target, check, &mut transaction::no_outputs)
155 }
156}