1mod addon_metadata;
5mod binary;
6mod error;
7mod gma_builder;
8mod gma_reader;
9mod result;
10
11pub use error::Error;
12pub use gma_builder::GMABuilder;
13pub use gma_reader::{FileEntry, GMAFile};
14pub use result::Result;
15use std::convert::TryFrom;
16
17use gma_reader::GMAFileReader;
18
19use std::io::BufReader;
20use std::{
21 io::{BufRead, Cursor, Seek},
22 path::Path,
23};
24
25const IDENT: [u8; 4] = [b'G', b'M', b'A', b'D'];
26const VALID_VERSIONS: [u8; 3] = [1, 2, 3];
27
28#[derive(Debug, Clone, Copy, PartialEq)]
29pub enum AddonType {
30 Gamemode,
31 Map,
32 Weapon,
33 Vehicle,
34 NPC,
35 Entity,
36 Tool,
37 Effects,
38 Model,
39 ServerContent,
40}
41
42impl TryFrom<&str> for AddonType {
43 type Error = Error;
44
45 fn try_from(value: &str) -> Result<Self, Self::Error> {
46 let value_lower = value.to_lowercase();
47 match value_lower.as_str() {
48 "gamemode" => Ok(AddonType::Gamemode),
49 "map" => Ok(AddonType::Map),
50 "weapon" => Ok(AddonType::Weapon),
51 "vehicle" => Ok(AddonType::Vehicle),
52 "npc" => Ok(AddonType::NPC),
53 "entity" => Ok(AddonType::Entity),
54 "tool" => Ok(AddonType::Tool),
55 "effects" => Ok(AddonType::Effects),
56 "model" => Ok(AddonType::Model),
57 "servercontent" => Ok(AddonType::ServerContent),
58 _ => Err(Self::Error::InvalidAddonType(value_lower)),
59 }
60 }
61}
62
63#[derive(Debug, Clone, Copy, PartialEq)]
64pub enum AddonTag {
65 Fun,
66 Roleplay,
67 Scenic,
68 Movie,
69 Realism,
70 Cartoon,
71 Water,
72 Comic,
73 Build,
74}
75
76impl TryFrom<&str> for AddonTag {
77 type Error = Error;
78
79 fn try_from(value: &str) -> Result<Self, Self::Error> {
80 let value_lower = value.to_lowercase();
81 match value_lower.as_str() {
82 "fun" => Ok(AddonTag::Fun),
83 "roleplay" => Ok(AddonTag::Roleplay),
84 "scenic" => Ok(AddonTag::Scenic),
85 "movie" => Ok(AddonTag::Movie),
86 "realism" => Ok(AddonTag::Realism),
87 "cartoon" => Ok(AddonTag::Cartoon),
88 "water" => Ok(AddonTag::Water),
89 "comic" => Ok(AddonTag::Comic),
90 "build" => Ok(AddonTag::Build),
91 _ => Err(Self::Error::InvalidAddonTag(value_lower)),
92 }
93 }
94}
95
96pub fn open<P>(path: P) -> Result<GMAFile<BufReader<std::fs::File>>>
98where
99 P: AsRef<Path>,
100{
101 let file = std::fs::File::open(path)?;
102 let reader = BufReader::new(file);
103 load(reader)
104}
105
106pub fn load<ReaderType>(r: ReaderType) -> Result<GMAFile<ReaderType>>
108where
109 ReaderType: BufRead + Seek,
110{
111 GMAFileReader::new(r)?.read_gma()
112}
113
114pub fn load_from_memory(data: &[u8]) -> Result<GMAFile<Cursor<&[u8]>>> {
116 load(Cursor::new(data))
117}