initial commit
This commit is contained in:
commit
4e60216b8e
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/target
|
1551
Cargo.lock
generated
Normal file
1551
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
12
Cargo.toml
Normal file
12
Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "printer-api"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
escpos = { version = "0.6.2", features = ["full"] }
|
||||||
|
graphql_client = { version = "0.13.0", features = ["graphql_query_derive" , "reqwest-blocking"] }
|
||||||
|
reqwest = { version = "0.11.24", features = ["json", "blocking"] }
|
||||||
|
serde = "1.0.196"
|
7
gql/GetItem.graphql
Normal file
7
gql/GetItem.graphql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
query GetItem($index: String!) {
|
||||||
|
magicItem(index: $index){
|
||||||
|
name,
|
||||||
|
rarity,
|
||||||
|
desc
|
||||||
|
}
|
||||||
|
}
|
19
gql/GetSpell.graphql
Normal file
19
gql/GetSpell.graphql
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
query GetSpell($index: String!){
|
||||||
|
spell(index: $index){
|
||||||
|
name,
|
||||||
|
level,
|
||||||
|
school {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
desc,
|
||||||
|
components,
|
||||||
|
duration,
|
||||||
|
ritual,
|
||||||
|
range,
|
||||||
|
casting_time,
|
||||||
|
area_of_effect {
|
||||||
|
size
|
||||||
|
type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1446
gql/schema.graphql
Normal file
1446
gql/schema.graphql
Normal file
File diff suppressed because it is too large
Load Diff
142
src/api_client.rs
Normal file
142
src/api_client.rs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
use crate::types::{Item, Spell};
|
||||||
|
use graphql_client::{GraphQLQuery, QueryBody, Response};
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
// https://studio.apollographql.com/sandbox?endpoint=https%3A%2F%2Fwww.dnd5eapi.co%2Fgraphql
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "gql/schema.graphql",
|
||||||
|
query_path = "gql/GetSpell.graphql",
|
||||||
|
response_derives = "Debug"
|
||||||
|
)]
|
||||||
|
struct GetSpell;
|
||||||
|
|
||||||
|
#[derive(GraphQLQuery)]
|
||||||
|
#[graphql(
|
||||||
|
schema_path = "gql/schema.graphql",
|
||||||
|
query_path = "gql/GetItem.graphql",
|
||||||
|
response_derives = "Debug"
|
||||||
|
)]
|
||||||
|
struct GetItem;
|
||||||
|
|
||||||
|
fn perform_request<Q>(
|
||||||
|
request_body: QueryBody<Q::Variables>,
|
||||||
|
) -> Result<Response<Q::ResponseData>, Box<dyn Error>>
|
||||||
|
where
|
||||||
|
Q: GraphQLQuery,
|
||||||
|
{
|
||||||
|
let client = reqwest::blocking::Client::new();
|
||||||
|
|
||||||
|
let res = client
|
||||||
|
.post("https://www.dnd5eapi.co/graphql")
|
||||||
|
.json(&request_body)
|
||||||
|
.send()?;
|
||||||
|
let response_body: Response<Q::ResponseData> = res.json()?;
|
||||||
|
|
||||||
|
return Ok(response_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spell_component_to_string(c: &get_spell::SpellComponent) -> String {
|
||||||
|
match c {
|
||||||
|
get_spell::SpellComponent::M => String::from("M"),
|
||||||
|
get_spell::SpellComponent::V => String::from("V"),
|
||||||
|
get_spell::SpellComponent::S => String::from("S"),
|
||||||
|
get_spell::SpellComponent::Other(s) => String::from(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rarity_to_string(r: &get_item::MagicItemRarity) -> String {
|
||||||
|
match r {
|
||||||
|
get_item::MagicItemRarity::ARTIFACT => String::from("ARTIFACT"),
|
||||||
|
get_item::MagicItemRarity::LEGENDARY => String::from("LEGENDARY"),
|
||||||
|
get_item::MagicItemRarity::VERY_RARE => String::from("VERY_RARE"),
|
||||||
|
get_item::MagicItemRarity::RARE => String::from("RARE"),
|
||||||
|
get_item::MagicItemRarity::UNCOMMON => String::from("UNCOMMON"),
|
||||||
|
get_item::MagicItemRarity::COMMON => String::from("COMMON"),
|
||||||
|
get_item::MagicItemRarity::VARIES => String::from("VARIES"),
|
||||||
|
get_item::MagicItemRarity::Other(s) => String::from(s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_spell(index: &str) -> Result<Spell, Box<dyn Error>> {
|
||||||
|
let vars = get_spell::Variables {
|
||||||
|
index: index.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let body = GetSpell::build_query(vars);
|
||||||
|
|
||||||
|
let res = perform_request::<GetSpell>(body)?;
|
||||||
|
|
||||||
|
match res.data {
|
||||||
|
Some(data) => match data.spell {
|
||||||
|
Some(spell) => {
|
||||||
|
let rtn = Spell {
|
||||||
|
name: spell.name,
|
||||||
|
level: spell.level,
|
||||||
|
school: spell.school.name,
|
||||||
|
range: spell.range,
|
||||||
|
desc: spell.desc.join(" "),
|
||||||
|
components: match spell.components {
|
||||||
|
Some(components) => {
|
||||||
|
Some(components
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.map(spell_component_to_string)
|
||||||
|
.collect::<Vec<String>>().join(" ")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
duration: spell.duration,
|
||||||
|
ritual: spell.ritual,
|
||||||
|
casting_time: spell.casting_time,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
return Err(Box::from("Spell not found"));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return Err(Box::from("Spell not found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_item(index: &str) -> Result<Item, Box<dyn Error>>{
|
||||||
|
let vars = get_item::Variables {
|
||||||
|
index: index.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let body = GetItem::build_query(vars);
|
||||||
|
|
||||||
|
let res = perform_request::<GetItem>(body)?;
|
||||||
|
|
||||||
|
match res.data {
|
||||||
|
Some(data) => {
|
||||||
|
match data.magic_item {
|
||||||
|
Some(item) => {
|
||||||
|
let rtn = Item{
|
||||||
|
name: item.name,
|
||||||
|
rarity: rarity_to_string(&item.rarity),
|
||||||
|
desc: item.desc.join(" ")
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(rtn);
|
||||||
|
}
|
||||||
|
|
||||||
|
None => {
|
||||||
|
return Err(Box::from("Item not found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None => {
|
||||||
|
return Err(Box::from("Item not found"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
35
src/main.rs
Normal file
35
src/main.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
mod print;
|
||||||
|
mod api_client;
|
||||||
|
mod types;
|
||||||
|
|
||||||
|
use escpos::{driver::{ConsoleDriver, FileDriver}, errors::PrinterError, printer::Printer, utils::Protocol};
|
||||||
|
|
||||||
|
// https://www.dnd5eapi.co/graphql
|
||||||
|
|
||||||
|
fn run() -> Result<(),PrinterError> {
|
||||||
|
// let driver = FileDriver::open(Path::new("/dev/usb/lp0")).unwrap();
|
||||||
|
let driver = ConsoleDriver::open(true);
|
||||||
|
let mut printer = Printer::new(driver, Protocol::default());
|
||||||
|
|
||||||
|
printer.init()?;
|
||||||
|
|
||||||
|
print::print_test_page(&mut printer)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main(){
|
||||||
|
let spell = api_client::get_spell("eldritch-blast").unwrap();
|
||||||
|
|
||||||
|
let driver = FileDriver::open(Path::new("/dev/usb/lp0")).unwrap();
|
||||||
|
let mut printer = Printer::new(driver, Protocol::default());
|
||||||
|
|
||||||
|
printer.init().unwrap();
|
||||||
|
|
||||||
|
print::print_spell(&mut printer, &spell).unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
println!("{:?}",spell);
|
||||||
|
}
|
129
src/print.rs
Normal file
129
src/print.rs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
use escpos::{driver::Driver, errors::PrinterError, printer::Printer, utils::JustifyMode};
|
||||||
|
|
||||||
|
use crate::types::Spell;
|
||||||
|
|
||||||
|
const WIDTH: usize = 32;
|
||||||
|
|
||||||
|
pub fn print_test_page<D: Driver>(printer: &mut Printer<D>) -> Result<(), PrinterError> {
|
||||||
|
printer
|
||||||
|
.writeln("---Printer Test Page---")?
|
||||||
|
.bold(true)?
|
||||||
|
.writeln("This text should be bold.")?
|
||||||
|
.bold(false)?
|
||||||
|
.underline(escpos::utils::UnderlineMode::Single)?
|
||||||
|
.writeln("This text should be single underline.")?
|
||||||
|
.underline(escpos::utils::UnderlineMode::Double)?
|
||||||
|
.writeln("This text should be double underline.")?
|
||||||
|
.underline(escpos::utils::UnderlineMode::None)?
|
||||||
|
.double_strike(true)?
|
||||||
|
.writeln("This text should be double striked.")?
|
||||||
|
.double_strike(true)?
|
||||||
|
.writeln("Text alignment")?
|
||||||
|
.justify(JustifyMode::CENTER)?
|
||||||
|
.writeln("CENTER")?
|
||||||
|
.justify(JustifyMode::RIGHT)?
|
||||||
|
.writeln("RIGHT")?
|
||||||
|
.justify(JustifyMode::LEFT)?
|
||||||
|
.size(1, 1)?
|
||||||
|
.writeln("size 1")?
|
||||||
|
.size(5, 5)?
|
||||||
|
.writeln("size 5")?
|
||||||
|
.reset_size()?
|
||||||
|
.font(escpos::utils::Font::A)?
|
||||||
|
.write("Font A ")?
|
||||||
|
.font(escpos::utils::Font::B)?
|
||||||
|
.write("Font B ")?
|
||||||
|
.font(escpos::utils::Font::C)?
|
||||||
|
.writeln("Font C")?
|
||||||
|
.font(escpos::utils::Font::A)?
|
||||||
|
.flip(true)?
|
||||||
|
.writeln("Fliped")?
|
||||||
|
.flip(false)?
|
||||||
|
.line_spacing(8)?
|
||||||
|
.writeln("Line")?
|
||||||
|
.writeln("Spacing")?
|
||||||
|
.reset_line_spacing()?
|
||||||
|
.upside_down(true)?
|
||||||
|
.writeln("Upside down")?
|
||||||
|
.upside_down(false)?
|
||||||
|
// Barcodes
|
||||||
|
.writeln("EAN-13 (978020137962)")?
|
||||||
|
.ean13("978020137962")?
|
||||||
|
.writeln("EAN-8 (9031101)")?
|
||||||
|
.ean8("9031101")?
|
||||||
|
.writeln("UPC-A")?
|
||||||
|
.upca("72527273070")?
|
||||||
|
.writeln("CODE-39")?
|
||||||
|
.code39("1234")?
|
||||||
|
.writeln("CODABAR")?
|
||||||
|
.writeln("1234")?
|
||||||
|
.writeln("ITF")?
|
||||||
|
.itf("1234")?
|
||||||
|
// 2D Codes
|
||||||
|
.writeln("QR Code")?
|
||||||
|
.qrcode("Hello world")?
|
||||||
|
.writeln("2D GS1 DataBar")?
|
||||||
|
.gs1_databar_2d("1234567890123")?
|
||||||
|
.writeln("pdf417")?
|
||||||
|
.pdf417("Hello world")?
|
||||||
|
.writeln("Maxi code")?
|
||||||
|
.maxi_code("Hello world")?
|
||||||
|
.writeln("Data matrix")?
|
||||||
|
.data_matrix("Hello world")?
|
||||||
|
.writeln("aztec")?
|
||||||
|
.aztec("Hello world")?
|
||||||
|
// Image
|
||||||
|
.writeln("raster image")?
|
||||||
|
// .bit_image("./rust-logo-small.png")?
|
||||||
|
.print()?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn left_right_print<D: Driver>(printer: &mut Printer<D>,left: &str, right: &str ) -> Result<(), PrinterError> {
|
||||||
|
printer
|
||||||
|
.write(left)?
|
||||||
|
.write(&".".repeat(WIDTH - left.len() - right.len()))?
|
||||||
|
.writeln(right)?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_spell<D: Driver>(printer: &mut Printer<D>, spell: &Spell) -> Result<(), PrinterError> {
|
||||||
|
printer
|
||||||
|
.size(4, 4)?
|
||||||
|
.writeln(&spell.name)?
|
||||||
|
.reset_size()?
|
||||||
|
.line_spacing(1)?;
|
||||||
|
|
||||||
|
if spell.level > 0 {
|
||||||
|
if spell.ritual {
|
||||||
|
printer.writeln(&format!("Lvl. {} {} (ritual)", spell.level, spell.school))?;
|
||||||
|
}else{
|
||||||
|
printer.writeln(&format!("Lvl. {} {}", spell.level, spell.school))?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printer.writeln(&format!("{} cantrip", spell.school))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
printer.feed()?;
|
||||||
|
|
||||||
|
match &spell.components {
|
||||||
|
Some(comp) => {
|
||||||
|
left_right_print(printer, "Components:", &comp)?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
left_right_print(printer, "Casting time:", &spell.casting_time)?;
|
||||||
|
left_right_print(printer, "Range:", &spell.range)?;
|
||||||
|
left_right_print(printer, "Duration:", &spell.duration)?;
|
||||||
|
|
||||||
|
printer
|
||||||
|
.reset_line_spacing()?
|
||||||
|
.write(&spell.desc)?
|
||||||
|
.feeds(3)?
|
||||||
|
.print()?;
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
18
src/types.rs
Normal file
18
src/types.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Spell{
|
||||||
|
pub name: String,
|
||||||
|
pub level: i64,
|
||||||
|
pub range: String,
|
||||||
|
pub school: String,
|
||||||
|
pub desc: String,
|
||||||
|
pub components: Option<String>,
|
||||||
|
pub duration: String,
|
||||||
|
pub ritual: bool,
|
||||||
|
pub casting_time: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Item {
|
||||||
|
pub name: String,
|
||||||
|
pub rarity: String,
|
||||||
|
pub desc: String,
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user