osrscache/loader/mod.rs
1//! Loaders for definitions.
2//!
3//! # Custom loaders
4//!
5//! If you need a certain loader and this crate doesn't provide it you can use the below
6//! example to help you make your own loader if you desperately need it.
7//!
8//! ```
9//! use std::{collections::HashMap, io::{ self, BufReader, }};
10//! use osrscache::{
11//! Cache, extension::ReadExt,
12//! definition::osrs::{ Definition, FetchDefinition },
13//! };
14//!
15//! fn main() -> Result<(), osrscache::Error> {
16//! let cache = Cache::new("./data/osrs_cache")?;
17//! let custom_loader = CustomLoader::new(&cache)?;
18//! let definition = custom_loader.load(1042);
19//!
20//! if let Some(def) = definition {
21//! println!("id: {}, name: {}", def.id, def.name);
22//! }
23//!
24//! Ok(())
25//! }
26//!
27//! // Newtype defining the loader.
28//! struct CustomLoader(HashMap<u16, CustomDefinition>);
29//!
30//! impl CustomLoader {
31//! fn new(cache: &Cache) -> Result<Self, osrscache::Error> {
32//! // Some definitions are all contained within one archive.
33//! // Other times one archive only contains one definition, but in most cases
34//! // for OSRS they are stored as multiple definitions per archive.
35//!
36//! let index_id = 2; // Config index.
37//! let archive_id = 10; // Contains all ItemDefinitions.
38//!
39//! let map = CustomDefinition::fetch_from_archive(cache, index_id, archive_id)?;
40//!
41//! Ok(Self(map))
42//! }
43//!
44//! // Simple HashMap lookup.
45//! fn load(&self, id: u16) -> Option<&CustomDefinition> {
46//! self.0.get(&id)
47//! }
48//! }
49//!
50//! // Your definition with all the required fields. (in this example it's just a ItemDefinition)
51//! #[derive(Default)]
52//! struct CustomDefinition {
53//! pub id: u16,
54//! pub name: String,
55//! }
56//!
57//! impl Definition for CustomDefinition {
58//! fn new(id: u16, buffer: &[u8]) -> Result<Self, osrscache::Error> {
59//! let mut reader = BufReader::new(buffer);
60//! let def = decode_buffer(id, &mut reader)?;
61//!
62//! Ok(def)
63//! }
64//! }
65//!
66//! fn decode_buffer(id: u16, reader: &mut BufReader<&[u8]>) -> io::Result<CustomDefinition> {
67//! // Parse the buffer into a definition.
68//! let mut def = CustomDefinition {
69//! id,
70//! .. CustomDefinition::default()
71//! };
72//!
73//! loop {
74//! let opcode = reader.read_u8()?;
75//!
76//! match opcode {
77//! // 0 indicates to stop parsing. Skipping for now because we are
78//! // only interested in the name.
79//! // 0 => break,
80//! 2 => { def.name = reader.read_string()?; break; },
81//! // Skipping the rest of the buffer for the sake of the example,
82//! // every opcode should be parsed into values of the definition.
83//! _ => { if reader.buffer().len() == 0 { break; } }
84//! // Should normally be:
85//! // _ => unreachable!()
86//! }
87//! }
88//!
89//! Ok(def)
90//! }
91//! ```
92
93/// OSRS loaders.
94pub mod osrs;