fips_md/runtime/
borrows.rs1use std::{sync::{RwLockReadGuard, RwLockWriteGuard}};
4
5use anyhow::{anyhow, Result};
6
7use crate::{
8 runtime::{ParticleID, ParticleIndexEntry, ParticleData},
9 parser::FipsType
10};
11
12use super::MemberData;
13
14pub struct FipsBorrow<'a> {
16 member_data: RwLockReadGuard<'a, MemberData>,
18 typ: FipsType
20}
21
22pub struct FipsBorrowMut<'a> {
24 member_data: RwLockWriteGuard<'a, MemberData>,
26 typ: FipsType
28}
29
30pub struct ParticleBorrowMut<'a> {
32 particle_id: ParticleID,
33 particle_definition: &'a ParticleIndexEntry,
34 particle_data: RwLockWriteGuard<'a, ParticleData>
35}
36
37impl<'a> ParticleBorrowMut<'a> {
38 pub(crate) fn new(particle_id: ParticleID, particle_definition: &'a ParticleIndexEntry,
39 particle_data: RwLockWriteGuard<'a, ParticleData>) -> Self
40 {
41 Self {
42 particle_id, particle_data, particle_definition
43 }
44 }
45
46 pub fn get_particle_id(&self) -> ParticleID {
48 self.particle_id
49 }
50
51 pub fn get_particle_count(&self) -> usize {
53 self.particle_data.get_particle_count()
54 }
55
56 pub fn borrow_member (&self, name: &str) -> Option<FipsBorrow> {
58 match self.particle_definition.get_member_by_name(name) {
59 None => None,
60 Some((member_id, member_definition)) => {
61 let member_data = self.particle_data.borrow_member(&member_id);
62 match member_data {
63 None => return None,
64 Some(member_data) => {
65 let typ = member_definition.get_type();
66 Some(FipsBorrow {
67 member_data,
68 typ: typ.clone()
69 })
70 }
71 }
72 }
73 }
74 }
75
76 pub fn borrow_member_mut (&self, name: &str) -> Option<FipsBorrowMut> {
78 match self.particle_definition.get_member_by_name(name) {
79 None => None,
80 Some((member_id, member_definition)) => {
81 let member_data = self.particle_data.borrow_member_mut(&member_id);
82 match member_data {
83 None => return None,
84 Some(member_data) => {
85 if member_data.is_uniform() {
86 panic!("Cannot borrow uniform member mutably. Use the uniform_members parameter in create_particles to initialize uniform members.");
87 }
88 else {
89 let typ = member_definition.get_type();
90 Some(FipsBorrowMut {
91 member_data, typ: typ.clone()
92 })
93 }
94 }
95 }
96 }
97 }
98 }
99}
100
101impl<'a> FipsBorrow<'a> {
102 pub fn as_i64(&self) -> Result<i64> {
104 if !self.member_data.is_uniform() {
105 Err(anyhow!("Cannot access member as single i64 since it is allocated per-particle. Did you mean as_i64_slice()?"))
106 }
107 else {
108 if self.typ.is_scalar() && self.typ.is_i64_derived() {
110 Ok(self.member_data.as_i64())
111 }
112 else {
113 Err(anyhow!("Member cannot be cast to single i64 (type was {})", self.typ))
114 }
115 }
116 }
117
118 pub fn as_f64(&self) -> Result<f64> {
120 if !self.member_data.is_uniform() {
121 Err(anyhow!("Cannot access member as single f64 since it is allocated per-particle. Did you mean as_f64_slice()?"))
122 }
123 else {
124 if self.typ.is_scalar() && self.typ.is_f64_derived() {
126 Ok(self.member_data.as_f64())
127 }
128 else {
129 Err(anyhow!("Member cannot be cast to single f64 (type was {})", self.typ))
130 }
131 }
132 }
133
134 pub fn as_f64_slice(&self) -> Result<&[f64]> {
136 if self.typ.is_f64_derived() {
138 Ok(self.member_data.as_f64_slice())
139 }
140 else {
141 Err(anyhow!("Member cannot be cast to slice of f64 (type was {})", self.typ))
142 }
143 }
144
145 pub fn as_i64_slice(&self) -> Result<&[i64]> {
147 if self.typ.is_i64_derived() {
149 Ok(self.member_data.as_i64_slice())
150 }
151 else {
152 Err(anyhow!("Member cannot be cast to slice of i64 (type was {})", self.typ))
153 }
154 }
155}
156
157impl<'a> FipsBorrowMut<'a> {
158 pub fn as_i64(&self) -> Result<i64> {
162 if !self.member_data.is_uniform() {
163 Err(anyhow!("Cannot access member as single i64 since it is allocated per-particle. Did you mean as_i64_slice()?"))
164 }
165 else {
166 if self.typ.is_scalar() && self.typ.is_i64_derived() {
168 Ok(self.member_data.as_i64())
169 }
170 else {
171 Err(anyhow!("Member cannot be cast to single i64 (type was {})", self.typ))
172 }
173 }
174 }
175
176 pub fn as_f64(&self) -> Result<f64> {
178 if !self.member_data.is_uniform() {
179 Err(anyhow!("Cannot access member as single f64 since it is allocated per-particle. Did you mean as_f64_slice()?"))
180 }
181 else {
182 if self.typ.is_scalar() && self.typ.is_f64_derived() {
184 Ok(self.member_data.as_f64())
185 }
186 else {
187 Err(anyhow!("Member cannot be cast to single f64 (type was {})", self.typ))
188 }
189 }
190 }
191
192 pub fn as_f64_slice(&mut self) -> Result<&mut [f64]> {
194 if self.typ.is_f64_derived() {
196 Ok(self.member_data.as_f64_slice_mut())
197 }
198 else {
199 Err(anyhow!("Member cannot be cast to slice of f64 (type was {})", self.typ))
200 }
201 }
202
203 pub fn as_i64_slice(&mut self) -> Result<&mut [i64]> {
205 if self.typ.is_i64_derived() {
207 Ok(self.member_data.as_i64_slice_mut())
208 }
209 else {
210 Err(anyhow!("Member cannot be cast to slice of i64 (type was {})", self.typ))
211 }
212 }
213}