1use std::any::Any;
2use std::{ptr, str, slice};
3use std::marker::PhantomData;
4use std::ops::{Deref, Index};
5use std::alloc::{self,Layout,System,GlobalAlloc};
6use std::ffi::c_void;
7use std::cmp::min;
8use std::io::{Read,Seek,SeekFrom};
9use std::fs::File;
10use std::mem;
11use std::string;
12use std::ptr::NonNull;
13use std::fmt::{self, Debug, Display, Formatter};
14use crate::{OpenFileInfo, RawThreadPool};
15use crate::generated::{RawStream, RawAllocator, RawVertexStream, Progress, ProgressResult, Error, Vec2, Vec3, Vec4};
16use crate::generated::format_error;
17
18pub type Real = f64;
19pub type ThreadPoolContext = usize;
20pub type OpenFileContext = usize;
21
22#[repr(C)]
23pub struct List<T> {
24 pub data: *const T,
25 pub count: usize,
26 _marker: PhantomData<T>,
27}
28
29impl<T> List<T> {
30 pub(crate) unsafe fn from_slice(slice: &[T]) -> List<T> {
31 List {
32 data: slice.as_ptr(),
33 count: slice.len(),
34 _marker: PhantomData,
35 }
36 }
37 pub(crate) unsafe fn as_static_ref(&self) -> &'static [T] {
38 slice_from_ptr(self.data, self.count)
39 }
40}
41
42impl<T> AsRef<[T]> for List<T> {
43 fn as_ref(&self) -> &[T] {
44 unsafe { slice_from_ptr(self.data, self.count) }
45 }
46}
47
48impl<T> Deref for List<T> {
49 type Target = [T];
50 fn deref(&self) -> &Self::Target {
51 unsafe { slice_from_ptr(self.data, self.count) }
52 }
53}
54
55impl<'a, T> IntoIterator for &'a List<T> {
56 type Item = &'a T;
57 type IntoIter = slice::Iter<'a, T>;
58 fn into_iter(self) -> Self::IntoIter {
59 self.as_ref().into_iter()
60 }
61}
62
63impl<T> Index<usize> for List<T> {
64 type Output = T;
65 fn index(&self, index: usize) -> &T {
66 &self.as_ref()[index]
67 }
68}
69
70#[repr(C)]
71pub struct RefList<T> {
72 data: *const Ref<T>,
73 pub count: usize,
74 _marker: PhantomData<T>,
75}
76
77impl<T> RefList<T> {
78 #[allow(dead_code)]
79 pub(crate) unsafe fn as_static_ref(&self) -> &'static [Ref<T>] {
80 slice_from_ptr(self.data, self.count)
81 }
82}
83
84impl<T> AsRef<[Ref<T>]> for RefList<T> {
85 fn as_ref(&self) -> &[Ref<T>] {
86 unsafe { slice_from_ptr(self.data, self.count) }
87 }
88}
89
90impl<T> Deref for RefList<T> {
91 type Target = [Ref<T>];
92 fn deref(&self) -> &Self::Target {
93 unsafe { slice_from_ptr(self.data, self.count) }
94 }
95}
96
97pub struct RefIter<'a, T> {
98 inner: slice::Iter<'a, Ref<T>>,
99}
100
101impl<'a, T> Iterator for RefIter<'a, T> {
102 type Item = &'a T;
103 fn next(&mut self) -> Option<Self::Item> {
104 self.inner.next().map(|v| v.as_ref())
105 }
106}
107
108impl<'a, T> IntoIterator for &'a RefList<T> {
109 type Item = &'a T;
110 type IntoIter = RefIter<'a, T>;
111 fn into_iter(self) -> RefIter<'a, T> {
112 RefIter::<'_, T> { inner: self.as_ref().into_iter() }
113 }
114}
115
116impl<T> Index<usize> for RefList<T> {
117 type Output = T;
118 fn index(&self, index: usize) -> &T {
119 &self.as_ref()[index]
120 }
121}
122
123#[repr(transparent)]
124pub struct Ref<T> {
125 ptr: NonNull<T>,
126 _marker: PhantomData<T>,
127}
128
129impl<T> AsRef<T> for Ref<T> {
130 fn as_ref(&self) -> &T {
131 unsafe { &*self.ptr.as_ptr() }
132 }
133}
134
135impl<T> Deref for Ref<T> {
136 type Target = T;
137 fn deref(&self) -> &Self::Target {
138 unsafe { &*self.ptr.as_ptr() }
139 }
140}
141
142#[repr(C)]
143pub struct RawString {
144 pub data: *const u8,
145 pub length: usize,
146}
147
148impl RawString {
149 fn new(s: &[u8]) -> Self {
150 RawString {
151 data: s.as_ptr(),
152 length: s.len(),
153 }
154 }
155}
156
157impl Default for RawString {
158 fn default() -> Self {
159 RawString {
160 data: ptr::null(),
161 length: 0,
162 }
163 }
164}
165
166#[repr(C)]
167pub struct RawBlob {
168 pub data: *const u8,
169 pub size: usize,
170}
171
172impl RawBlob {
173 fn new(s: &[u8]) -> Self {
174 RawBlob {
175 data: s.as_ptr(),
176 size: s.len(),
177 }
178 }
179}
180
181impl Default for RawBlob {
182 fn default() -> Self {
183 RawBlob {
184 data: ptr::null(),
185 size: 0,
186 }
187 }
188}
189
190#[repr(C)]
191pub struct RawList<T> {
192 pub data: *const T,
193 pub count: usize,
194}
195
196impl<T> Default for RawList<T> {
197 fn default() -> Self {
198 RawList {
199 data: ptr::null(),
200 count: 0,
201 }
202 }
203}
204
205#[repr(C)]
206#[allow(dead_code)] pub struct OptionRef<T> {
208 ptr: *const T,
209 _marker: PhantomData<T>,
210}
211
212impl<T> OptionRef<T> {
213 pub fn is_some(&self) -> bool { self.ptr.is_null() }
214 pub fn is_none(&self) -> bool { !self.ptr.is_null() }
215
216 pub fn as_ref(&self) -> Option<&T> {
217 unsafe { self.ptr.as_ref() }
218 }
219}
220
221#[repr(C)]
222pub struct String {
223 data: *const u8,
224 pub length: usize,
225 _marker: PhantomData<u8>,
226}
227
228impl String {
229 pub(crate) unsafe fn as_static_ref(&self) -> &'static str {
230 str::from_utf8_unchecked(slice_from_ptr(self.data, self.length))
231 }
232}
233
234impl AsRef<str> for String {
235 fn as_ref(&self) -> &str {
236 unsafe { str::from_utf8_unchecked(slice_from_ptr(self.data, self.length)) }
237 }
238}
239
240impl Deref for String {
241 type Target = str;
242 fn deref(&self) -> &Self::Target {
243 self.as_ref()
244 }
245}
246
247impl Default for String {
248 fn default () -> String {
249 String{ data: ptr::null(), length: 0, _marker: PhantomData }
250 }
251}
252
253impl Display for String {
254 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
255 f.write_str(self.deref())
256 }
257}
258
259impl<'a> PartialEq<&'a str> for String {
260 fn eq(&self, rhs: &&'a str) -> bool {
261 &self.as_ref() == rhs
262 }
263}
264
265impl Debug for String {
266 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
267 write!(f, "{:?}", self.as_ref())
268 }
269}
270
271#[repr(C)]
272pub struct Blob {
273 data: *const u8,
274 pub size: usize,
275 _marker: PhantomData<u8>,
276}
277
278unsafe fn slice_from_ptr<'a, T>(data: *const T, len: usize) -> &'a [T] {
279 if len > 0 {
280 slice::from_raw_parts(data, len)
281 } else {
282 &[]
283 }
284}
285
286unsafe fn slice_from_ptr_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
287 if len > 0 {
288 slice::from_raw_parts_mut(data, len)
289 } else {
290 &mut []
291 }
292}
293
294impl Deref for Blob {
295 type Target = [u8];
296 fn deref(&self) -> &Self::Target {
297 unsafe { slice_from_ptr(self.data, self.size) }
298 }
299}
300
301pub trait AllocatorInterface {
302 fn alloc(&mut self, layout: Layout) -> *mut u8;
303 fn free(&mut self, ptr: *mut u8, layout: Layout);
304 fn realloc(&mut self, ptr: *mut u8, old_layout: Layout, new_layout: Layout) -> *mut u8 {
305 self.free(ptr, old_layout);
306 self.alloc(new_layout)
307 }
308 fn free_allocator(&mut self) { }
309}
310
311#[repr(transparent)]
312#[derive(Default)]
313pub struct Unsafe<T>(T);
314
315impl<T> Unsafe<T> {
316 pub unsafe fn new(t: T) -> Self { Self(t) }
317}
318
319impl<T> Unsafe<T> where T: Default {
320 pub fn take(&mut self) -> T { mem::take(&mut self.0) }
321}
322
323pub trait StreamInterface {
324 fn read(&mut self, buf: &mut [u8]) -> Option<usize>;
325 fn skip(&mut self, bytes: usize) -> bool {
326 #![allow(deprecated)]
327 unsafe {
328 let mut local_buf: [mem::MaybeUninit<u8>; 512] = mem::MaybeUninit::uninit().assume_init();
329 let mut left = bytes;
330 while left > 0 {
331 let to_read = min(left, local_buf.len());
332 let num_read = self.read(mem::transmute(&mut local_buf[0..to_read])).unwrap_or(0);
333 if num_read != to_read { return false }
334 left -= num_read
335 }
336 true
337 }
338 }
339 fn size(&mut self) -> u64 { 0 }
340 fn close(&mut self) { }
341}
342
343pub enum Stream {
344 File(File),
345 Read(Box<dyn Read>),
346 Box(Box<dyn StreamInterface>),
347 Raw(Unsafe<RawStream>),
348}
349
350unsafe extern "C" fn global_alloc(_user: *mut c_void, size: usize) -> *mut c_void {
351 let layout = Layout::from_size_align(size, 8).unwrap();
352 alloc::alloc(layout) as *mut _
353}
354
355unsafe extern "C" fn global_realloc(_user: *mut c_void, ptr: *mut c_void, old_size: usize, new_size: usize) -> *mut c_void {
356 let old_layout = Layout::from_size_align(old_size, 8).unwrap();
357 alloc::realloc(ptr as *mut _, old_layout, new_size) as *mut _
358}
359
360unsafe extern "C" fn global_free(_user: *mut c_void, ptr: *mut c_void, size: usize) {
361 let layout = Layout::from_size_align(size, 8).unwrap();
362 alloc::dealloc(ptr as *mut _, layout)
363}
364
365unsafe extern "C" fn system_alloc(_user: *mut c_void, size: usize) -> *mut c_void {
366 let layout = Layout::from_size_align(size, 8).unwrap();
367 System.alloc(layout) as *mut _
368}
369
370unsafe extern "C" fn system_realloc(_user: *mut c_void, ptr: *mut c_void, old_size: usize, new_size: usize) -> *mut c_void {
371 let old_layout = Layout::from_size_align(old_size, 8).unwrap();
372 System.realloc(ptr as *mut _, old_layout, new_size) as *mut _
373}
374
375unsafe extern "C" fn system_free(_user: *mut c_void, ptr: *mut c_void, size: usize) {
376 let layout = Layout::from_size_align(size, 8).unwrap();
377 System.dealloc(ptr as *mut _, layout)
378}
379
380unsafe extern "C" fn allocator_imp_alloc(user: *mut c_void, size: usize) -> *mut c_void {
381 let ator: &mut Box<dyn AllocatorInterface> = &mut *(user as *mut Box<dyn AllocatorInterface>);
382 let layout = Layout::from_size_align(size, 8).unwrap();
383 ator.alloc(layout) as *mut _
384}
385
386unsafe extern "C" fn allocator_imp_realloc(user: *mut c_void, ptr: *mut c_void, old_size: usize, new_size: usize) -> *mut c_void {
387 let ator: &mut Box<dyn AllocatorInterface> = &mut *(user as *mut Box<dyn AllocatorInterface>);
388 let old_layout = Layout::from_size_align(old_size, 8).unwrap();
389 let new_layout = Layout::from_size_align(new_size, 8).unwrap();
390 ator.realloc(ptr as *mut _, old_layout, new_layout) as *mut _
391}
392
393unsafe extern "C" fn allocator_imp_free(user: *mut c_void, ptr: *mut c_void, size: usize) {
394 let ator: &mut Box<dyn AllocatorInterface> = &mut *(user as *mut Box<dyn AllocatorInterface>);
395 let layout = Layout::from_size_align(size, 8).unwrap();
396 ator.free(ptr as *mut _, layout)
397}
398
399unsafe extern "C" fn allocator_imp_box_free_allocator(user: *mut c_void) {
400 let mut ator = Box::from_raw(user as *mut Box<dyn AllocatorInterface>);
401 ator.free_allocator()
402}
403
404pub enum Allocator {
405 Libc,
406 Global,
407 System,
408 Box(Box<dyn AllocatorInterface>),
409 Raw(Unsafe<RawAllocator>),
410}
411
412impl Default for Allocator {
413 fn default() -> Self { Allocator::Global }
414}
415
416impl Allocator {
417 pub(crate) fn from_rust(&self) -> RawAllocator {
418 match self {
419 Allocator::Libc => RawAllocator {
420 alloc_fn: None,
421 realloc_fn: None,
422 free_fn: None,
423 free_allocator_fn: None,
424 user: ptr::null::<c_void>() as *mut c_void,
425 },
426 Allocator::Global => RawAllocator {
427 alloc_fn: Some(global_alloc),
428 realloc_fn: Some(global_realloc),
429 free_fn: Some(global_free),
430 free_allocator_fn: None,
431 user: ptr::null::<c_void>() as *mut c_void,
432 },
433 Allocator::System => RawAllocator {
434 alloc_fn: Some(system_alloc),
435 realloc_fn: Some(system_realloc),
436 free_fn: Some(system_free),
437 free_allocator_fn: None,
438 user: ptr::null::<c_void>() as *mut c_void,
439 },
440 _ => panic!("required mutable reference"),
441 }
442 }
443 pub(crate) fn from_rust_mut(&mut self) -> RawAllocator {
444 match self {
445 Allocator::Box(b) => RawAllocator {
446 alloc_fn: Some(allocator_imp_alloc),
447 realloc_fn: Some(allocator_imp_realloc),
448 free_fn: Some(allocator_imp_free),
449 free_allocator_fn: Some(allocator_imp_box_free_allocator),
450 user: Box::into_raw(Box::new(b)) as *mut _,
451 },
452 Allocator::Raw(raw) => raw.take(),
453 _ => Self::from_rust(self),
454 }
455 }
456}
457
458pub enum ThreadPool {
459 None,
460 Raw(Unsafe<RawThreadPool>),
461}
462
463impl Default for ThreadPool {
464 fn default() -> Self { ThreadPool::None }
465}
466impl ThreadPool {
467 pub(crate) fn from_rust(&self) -> RawThreadPool {
468 match self {
469 ThreadPool::None => RawThreadPool {
470 init_fn: None,
471 run_fn: None,
472 wait_fn: None,
473 free_fn: None,
474 user: ptr::null::<c_void>() as *mut c_void,
475 },
476 _ => panic!("required mutable reference"),
477 }
478 }
479 pub(crate) fn from_rust_mut(&mut self) -> RawThreadPool {
480 match self {
481 ThreadPool::None => RawThreadPool {
482 init_fn: None,
483 run_fn: None,
484 wait_fn: None,
485 free_fn: None,
486 user: ptr::null::<c_void>() as *mut c_void,
487 },
488 ThreadPool::Raw(raw) => raw.take(),
489 }
490 }
491}
492
493pub struct VertexStream<'a> {
494 pub(crate) data: *mut c_void,
495 pub(crate) vertex_count: usize,
496 pub(crate) vertex_size: usize,
497 _marker: PhantomData<&'a mut ()>,
498}
499
500impl VertexStream<'_> {
501 pub fn new<T: Copy + Sized>(data: &mut [T]) -> VertexStream<'_> {
502 return VertexStream {
503 data: data.as_mut_ptr() as *mut c_void,
504 vertex_count: data.len(),
505 vertex_size: mem::size_of::<T>(),
506 _marker: PhantomData,
507 }
508 }
509}
510
511impl<'a> FromRust for [VertexStream<'a>] {
512 type Result = Vec<RawVertexStream>;
513 fn from_rust_mut(&mut self, _arena: &mut Arena) -> Self::Result {
514 self.iter().map(|s| RawVertexStream {
515 data: s.data,
516 vertex_count: s.vertex_count,
517 vertex_size: s.vertex_size,
518 }).collect()
519 }
520}
521
522unsafe extern "C" fn stream_read_read(user: *mut c_void, buf: *mut c_void, size: usize) -> usize {
523 let imp = &mut *(user as *mut Box<dyn Read>);
524 imp.read(slice_from_ptr_mut(buf as *mut u8, size)).unwrap_or(usize::MAX)
525}
526
527unsafe extern "C" fn stream_read_close(user: *mut c_void) {
528 let _ = Box::from_raw(user as *mut Box<dyn Read>);
529}
530
531unsafe extern "C" fn stream_imp_read(user: *mut c_void, buf: *mut c_void, size: usize) -> usize {
532 let imp = &mut *(user as *mut Box<dyn StreamInterface>);
533 imp.read(slice_from_ptr_mut(buf as *mut u8, size)).unwrap_or(usize::MAX)
534}
535
536unsafe extern "C" fn stream_imp_skip(user: *mut c_void, size: usize) -> bool {
537 let imp = &mut *(user as *mut Box<dyn StreamInterface>);
538 imp.skip(size)
539}
540
541unsafe extern "C" fn stream_imp_size(user: *mut c_void) -> u64 {
542 let imp = &mut *(user as *mut Box<dyn StreamInterface>);
543 imp.size()
544}
545
546unsafe extern "C" fn stream_imp_box_close(user: *mut c_void) {
547 let mut imp = Box::from_raw(user as *mut Box<dyn StreamInterface>);
548 imp.close()
549}
550
551#[allow(dead_code)]
553struct StreamRead<T: Read>(T);
554
555impl<T: Read> StreamInterface for StreamRead<T> {
556 fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
557 self.0.read(buf).ok()
558 }
559}
560
561struct StreamReadSeek<T: Read + Seek>(T);
562
563impl<T: Read + Seek> StreamInterface for StreamReadSeek<T> {
564 fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
565 self.0.read(buf).ok()
566 }
567 fn skip(&mut self, bytes: usize) -> bool {
568 match self.0.stream_position() {
569 Ok(cur) => match self.0.seek(SeekFrom::Current(bytes as i64)) {
570 Ok(pos) => pos == cur + (bytes as u64),
571 Err(_) => false,
572 },
573 Err(_) => false,
574 }
575 }
576 fn size(&mut self) -> u64 {
577 if let Ok(start) = self.0.stream_position() {
578 if let Ok(end) = self.0.seek(SeekFrom::End(0)) {
579 if self.0.seek(SeekFrom::Start(start)).is_ok() {
580 return end - start
581 } else {
582 return u64::MAX
583 }
584 }
585 }
586 0
587 }
588}
589
590impl Stream {
591 pub(crate) fn from_rust_mut(&mut self) -> RawStream {
592 let local = mem::replace(self, Stream::Raw(unsafe { Unsafe::new(Default::default()) }));
593 match local {
594 Stream::File(file) => {
595 let mut inner = Stream::Box(Box::new(StreamReadSeek(file)));
596 inner.from_rust_mut()
597 },
598 Stream::Read(b) => RawStream {
599 read_fn: Some(stream_read_read),
600 skip_fn: None,
601 size_fn: None,
602 close_fn: Some(stream_read_close),
603 user: Box::into_raw(Box::new(b)) as *mut _,
604 },
605 Stream::Box(b) => RawStream {
606 read_fn: Some(stream_imp_read),
607 skip_fn: Some(stream_imp_skip),
608 size_fn: Some(stream_imp_size),
609 close_fn: Some(stream_imp_box_close),
610 user: Box::into_raw(Box::new(b)) as *mut _,
611 },
612 Stream::Raw(mut raw) => raw.take(),
613 }
614 }
615}
616
617pub unsafe extern "C" fn call_progress_cb<F>(user: *mut c_void, progress: *const Progress) -> ProgressResult
618 where F: FnMut(&Progress) -> ProgressResult
619{
620 let func: &mut F = &mut *(user as *mut F);
621 (func)(&*progress)
622}
623
624pub unsafe extern "C" fn call_open_file_cb<F>(user: *mut c_void, dst: *mut RawStream, path: *const u8, path_len: usize, info: *const OpenFileInfo) -> bool
625 where F: FnMut(&str, &OpenFileInfo) -> Option<Stream>
626{
627 let func: &mut F = &mut *(user as *mut F);
628
629 let path_str = match str::from_utf8(slice_from_ptr(path, path_len)) {
630 Ok(path_str) => path_str,
631 Err(_) => return false,
632 };
633
634 let mut stream = match (func)(path_str, &*info) {
635 Some(stream) => stream,
636 None => return false,
637 };
638
639 *dst = stream.from_rust_mut();
640 true
641}
642
643pub unsafe extern "C" fn call_close_memory_cb<F>(user: *mut c_void, data: *mut c_void, data_size: usize)
644 where F: FnMut(*mut c_void, usize) -> ()
645{
646 let func: &mut F = &mut *(user as *mut F);
647 (func)(data, data_size)
648}
649
650#[repr(transparent)]
651pub struct InlineBuf<T> {
652 pub data: mem::MaybeUninit<T>,
653}
654
655impl<T> Default for InlineBuf<T> {
656 fn default() -> Self {
657 Self { data: mem::MaybeUninit::uninit() }
658 }
659}
660
661impl Debug for Error {
662 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
663 #![allow(deprecated)]
664 unsafe {
665 let mut local_buf: [mem::MaybeUninit<u8>; 1024] = mem::MaybeUninit::uninit().assume_init();
666 let length = format_error(mem::transmute(local_buf.as_mut_slice()), self);
667 f.write_str(str::from_utf8_unchecked(mem::transmute(&local_buf[..length])))
668 }
669 }
670}
671
672#[repr(C)]
673pub struct ExternalRef<'a, T> {
674 data: T,
675 _marker: PhantomData<&'a T>,
676}
677
678impl<'a, T> ExternalRef<'a, T> {
679 pub unsafe fn new(t: T) -> Self {
680 Self {
681 data: t,
682 _marker: PhantomData,
683 }
684 }
685}
686
687impl<'a, T> AsRef<T> for ExternalRef<'a, T> {
688 fn as_ref(&self) -> &T {
689 &self.data
690 }
691}
692
693impl<'a, T> Deref for ExternalRef<'a, T> {
694 type Target = T;
695 fn deref(&self) -> &Self::Target {
696 &self.data
697 }
698}
699
700pub(crate) struct Arena {
701 items: Vec<Box<dyn Any>>,
702}
703
704impl Arena {
705 pub fn new() -> Arena {
706 Arena{
707 items: Vec::new(),
708 }
709 }
710
711 #[allow(unused)]
712 pub fn push_box<T: 'static>(&mut self, s: Box<T>) -> *const T {
713 let ptr = Box::as_ref(&s) as *const T;
714 self.items.push(s);
715 ptr
716 }
717 pub fn push_vec<T: 'static>(&mut self, vec: Vec<T>) -> *const T {
718 if vec.len() == 0 { return ptr::null(); }
719 let ptr = vec.as_ptr();
720 self.items.push(Box::new(vec));
721 ptr
722 }
723}
724
725pub fn format_flags(f: &mut fmt::Formatter<'_>, names: &[(&str, u32)], value: u32) -> fmt::Result {
726 let mut has_any = false;
727
728 for (name, v) in names {
729 if (value & v) != 0 {
730 let prefix = if has_any { "|" } else { "" };
731 has_any = true;
732 write!(f, "{}{}", prefix, name)?;
733 }
734 }
735
736 if !has_any {
737 write!(f, "NONE")?;
738 }
739
740 Ok(())
741}
742
743impl fmt::Display for Vec2 {
744 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
745 match (f.precision(), f.sign_plus()) {
746 (None, false) => write!(f, "({}, {})", self.x, self.y),
747 (None, true) => write!(f, "({:+}, {:+})", self.x, self.y),
748 (Some(p), false) => write!(f, "({1:.0$}, {2:.0$})", p, self.x, self.y),
749 (Some(p), true) => write!(f, "({1:+.0$}, {2:+.0$})", p, self.x, self.y),
750 }
751 }
752}
753
754impl fmt::Display for Vec3 {
755 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
756 match (f.precision(), f.sign_plus()) {
757 (None, false) => write!(f, "({}, {}, {})", self.x, self.y, self.z),
758 (None, true) => write!(f, "({:+}, {:+}, {:+})", self.x, self.y, self.z),
759 (Some(p), false) => write!(f, "({1:.0$}, {2:.0$}, {3:.0$})", p, self.x, self.y, self.z),
760 (Some(p), true) => write!(f, "({1:+.0$}, {2:+.0$}, {3:+.0$})", p, self.x, self.y, self.z),
761 }
762 }
763}
764
765impl fmt::Display for Vec4 {
766 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
767 match (f.precision(), f.sign_plus()) {
768 (None, false) => write!(f, "({}, {}, {}, {})", self.x, self.y, self.z, self.w),
769 (None, true) => write!(f, "({:+}, {:+}, {:+}, {})", self.x, self.y, self.z, self.w),
770 (Some(p), false) => write!(f, "({1:.0$}, {2:.0$}, {3:.0$}, {4:.0$})", p, self.x, self.y, self.z, self.w),
771 (Some(p), true) => write!(f, "({1:+.0$}, {2:+.0$}, {3:+.0$}, {4:+.0$})", p, self.x, self.y, self.z, self.w),
772 }
773 }
774}
775
776pub(crate) trait FromRust {
777 type Result: 'static;
778 fn from_rust(&self, _arena: &mut Arena) -> Self::Result {
779 panic!("type must be used via mutable reference")
780 }
781 fn from_rust_mut(&mut self, arena: &mut Arena) -> Self::Result {
782 self.from_rust(arena)
783 }
784}
785
786pub enum StringOpt<'a> {
787 Unset,
788 Ref(&'a str),
789 Owned(string::String),
790}
791
792impl Default for StringOpt<'_> {
793 fn default() -> Self {
794 StringOpt::Unset
795 }
796}
797
798impl<'a> From<&'a str> for StringOpt<'a> {
799 fn from(v: &'a str) -> Self {
800 StringOpt::Ref(v)
801 }
802}
803
804impl<'a> From<string::String> for StringOpt<'a> {
805 fn from(v: string::String) -> Self {
806 StringOpt::Owned(v)
807 }
808}
809
810impl<'a> FromRust for StringOpt<'a> {
811 type Result = RawString;
812 fn from_rust(&self, _arena: &mut Arena) -> Self::Result {
813 match self {
814 StringOpt::Unset => RawString::default(),
815 StringOpt::Ref(r) => RawString::new(r.as_bytes()),
816 StringOpt::Owned(r) => RawString::new(r.as_bytes()),
817 }
818 }
819}
820
821pub enum BlobOpt<'a> {
822 Unset,
823 Ref(&'a [u8]),
824 Owned(Vec<u8>),
825}
826
827impl Default for BlobOpt<'_> {
828 fn default() -> Self {
829 BlobOpt::Unset
830 }
831}
832
833impl<'a> From<&'a [u8]> for BlobOpt<'a> {
834 fn from(v: &'a [u8]) -> Self {
835 BlobOpt::Ref(v)
836 }
837}
838
839impl<'a> From<Vec<u8>> for BlobOpt<'a> {
840 fn from(v: Vec<u8>) -> Self {
841 BlobOpt::Owned(v)
842 }
843}
844
845impl<'a> FromRust for BlobOpt<'a> {
846 type Result = RawBlob;
847 fn from_rust(&self, _arena: &mut Arena) -> Self::Result {
848 match self {
849 BlobOpt::Unset => RawBlob::default(),
850 BlobOpt::Ref(r) => RawBlob::new(r),
851 BlobOpt::Owned(r) => RawBlob::new(r.as_slice()),
852 }
853 }
854}
855
856pub enum ListOpt<'a, T> {
857 Unset,
858 Ref(&'a [T]),
859 Mut(&'a mut [T]),
860 Owned(Vec<T>),
861}
862
863impl<T> Default for ListOpt<'_, T> {
864 fn default() -> Self {
865 ListOpt::Unset
866 }
867}
868
869impl<'a, T> From<&'a [T]> for ListOpt<'a, T> {
870 fn from(v: &'a [T]) -> Self {
871 ListOpt::Ref(v)
872 }
873}
874
875impl<'a, T> From<Vec<T>> for ListOpt<'a, T> {
876 fn from(v: Vec<T>) -> Self {
877 ListOpt::Owned(v)
878 }
879}
880
881impl<'a, T: FromRust> FromRust for ListOpt<'a, T> {
882 type Result = RawList<T::Result>;
883
884 fn from_rust(&self, arena: &mut Arena) -> Self::Result {
885 let items: Vec<T::Result> = match self {
886 ListOpt::Unset => return RawList::default(),
887 ListOpt::Ref(v) => v.iter().map(|v| T::from_rust(v, arena)).collect(),
888 ListOpt::Mut(v) => v.iter().map(|v| T::from_rust(v, arena)).collect(),
889 ListOpt::Owned(v) => v.iter().map(|v| T::from_rust(v, arena)).collect(),
890 };
891 let count = items.len();
892 RawList { data: arena.push_vec(items), count }
893 }
894
895 fn from_rust_mut(&mut self, arena: &mut Arena) -> Self::Result {
896 let items: Vec<T::Result> = match mem::take(self) {
897 ListOpt::Unset => return RawList::default(),
898 ListOpt::Ref(v) => v.iter().map(|v| T::from_rust(v, arena)).collect(),
899 ListOpt::Mut(v) => v.into_iter().map(|v| T::from_rust_mut(v, arena)).collect(),
900 ListOpt::Owned(v) => v.into_iter().map(|mut v| T::from_rust_mut(&mut v, arena)).collect(),
901 };
902 let count = items.len();
903 RawList { data: arena.push_vec(items), count }
904 }
905
906}
907
908impl<T: Copy + 'static> FromRust for T {
909 type Result = T;
910 fn from_rust(&self, _arena: &mut Arena) -> Self::Result {
911 *self
912 }
913}