1use std::ffi::CString;
2use std::fmt::Debug;
3use std::fs;
4
5use libc::{c_int, c_uint, c_void};
6use thiserror::Error;
7
8use crate::ffi::{is_window_ready, load_render_texture, load_texture};
9
10#[repr(C)]
12#[derive(Debug, Clone, PartialEq)]
13pub struct Texture {
14 pub id: c_uint,
16 pub width: c_int,
18 pub height: c_int,
20 pub mipmaps: c_int,
22 pub format: c_int,
24}
25
26#[repr(C)]
28#[derive(Debug, Clone)]
29pub struct Image {
30 pub data: *mut c_void,
32 pub width: c_int,
34 pub height: c_int,
36 pub mipmaps: c_int,
38 pub format: c_int,
40}
41
42#[repr(C)]
44#[derive(Debug, Clone)]
45pub struct RenderTexture {
46 pub id: c_uint,
48 pub texture: Texture,
50 pub depth: Texture,
52}
53pub type RenderTexture2D = RenderTexture;
54
55#[derive(Error)]
56pub enum TextureLoadError {
57 #[error("could not find file at path: {0}")]
58 FileNotFound(String),
59 #[error("you must first create a Window before loading textures")]
60 WindowNotReady(),
61}
62
63impl Debug for TextureLoadError {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 write!(f, "{self}")
66 }
67}
68
69impl Texture {
70 pub fn new(path: String) -> Result<Self, TextureLoadError> {
71 let window_ready = unsafe { is_window_ready() };
72 if !window_ready {
73 return Err(TextureLoadError::WindowNotReady());
74 }
75 let metadata = fs::metadata(&path);
76 if metadata.is_err() {
77 return Err(TextureLoadError::FileNotFound(path));
78 }
79 if !metadata.unwrap().is_file() {
80 return Err(TextureLoadError::FileNotFound(path));
81 }
82
83 unsafe { Ok(load_texture(CString::new(path).unwrap().as_ptr())) }
84 }
85}
86
87#[derive(Error)]
88pub enum RenderTextureLoadError {
89 #[error("you must first create a Window before loading textures")]
90 WindowNotReady(),
91}
92
93impl Debug for RenderTextureLoadError {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 write!(f, "{self}")
96 }
97}
98
99impl RenderTexture {
100 pub fn new(width: i32, height: i32) -> Result<RenderTexture, RenderTextureLoadError> {
101 if unsafe { !is_window_ready() } {
102 return Err(RenderTextureLoadError::WindowNotReady());
103 }
104
105 unsafe { Ok(load_render_texture(width, height)) }
106 }
107}