Skip to content

Commit

Permalink
Merge pull request #23 from naomijub/generate-qrcode
Browse files Browse the repository at this point in the history
generates qrcode files and string
  • Loading branch information
naomijub authored Oct 9, 2020
2 parents 6629870 + c47edd2 commit e21e060
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 6 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "brcode"
version = "1.3.1"
version = "1.4.0"
authors = ["Julia Naomi <[email protected]>"]
edition = "2018"
description = "Crate to parse and emit BR Codes"
Expand All @@ -23,6 +23,7 @@ edn-derive = "0.4.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_derive = "1"
qrcode-generator = "4.0.3"

[dev-dependencies]
criterion = "0.3"
Expand Down
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A crate to parse and emit [PIX BR Code](https://www.bcb.gov.br/content/estabilid

```toml
[dependencies]
brcode = "1.3.1"
brcode = "1.4.0"
```

### Build from source
Expand Down Expand Up @@ -282,12 +282,27 @@ fn brcode_value() -> BrCode {
}
```

**`BrCode` functions**
**`BrCode` functions** context related
* `pub fn is_pix(&self) -> bool` determines if BrCode is a `PIX` transaction.
* `pub fn get_transaction_id(&self) -> Option<String>` gets `transaction_id` value (field 5 of item 65).
* `pub fn get_alias(&self) -> Option<Vec<String>>` gets all possible values for PIX aliases. Usually only field 1 of item 26 is valid. Checks if the alias if of type `"BR.GOV.BCB.PIX"`.
* `pub fn get_message(&self) -> Option<Vec<String>>` gets all possible massages for PIX aliases. Usually only field 2 of item 26 is valid. Checks if the alias if of type `"BR.GOV.BCB.PIX"`.

**`BrCode` functions** QrCode generation related:
* `to_svg_string(&self, ecc: QrCodeEcc, size: usize) -> String` generates a SVG xml in a String.
* `to_svg_standard_string(&self) -> String` generates a SVG xml in a String with `QrCodeEcc::Low` and `size = 1024`.
* `to_vec_u8(&self, ecc: QrCodeEcc, size: usize) -> Vec<u8>` generates a PNG formatted in `Vec<u8>`.
* `to_svg_file(&self, file_path: &str, ecc: QrCodeEcc, size: usize)` creates a QR Code in format `.svg` located at file path `file_path`.
* `to_standard_svg_file(&self, file_path: &str)` creates a QR Code in format `.svg` located at file path `file_path` with `QrCodeEcc::Low` and `size = 1024`.
* `to_png_file(&self, file_path: &str, ecc: QrCodeEcc, size: usize)` creates a QR Code in format `.png` located at file path `file_path`.

* `file_path` examples are `tests/data/file_output.png` and `tests/data/file_output.svg` from the project root. If directory doesn't exist an error will be thrown.
* `QrCodeEcc` is the error correction level in a QR Code symbol and `size` is the image size.
* `QrCodeEcc::Low` The QR Code can tolerate about 7% erroneous codewords.
* `QrCodeEcc::Medium` The QR Code can tolerate about 15% erroneous codewords.
* `QrCodeEcc::Quartile` The QR Code can tolerate about 25% erroneous codewords.
* `QrCodeEcc::High` The QR Code can tolerate about 30% erroneous codewords.

## Benchmark

**from_str** in `benches/parse.rs`
Expand Down
41 changes: 38 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub(crate) mod parse;
pub use aux::crc16_ccitt;
pub use model::{BrCode, Info, Label, MerchantInfo, Template};
pub use parse::Data;
pub use qrcode_generator::QrCodeEcc;

pub fn from_str(code: &str) -> Vec<(usize, parse::Data)> {
parse::parse(code, 99)
Expand Down Expand Up @@ -65,6 +66,23 @@ pub extern "C" fn edn_to_brcode(edn: *const c_char) -> *const c_char {
to_c_char(&brcode_to_string(brcode))
}

#[no_mangle]
pub extern "C" fn edn_to_svg_brcode(edn: *const c_char) -> *const c_char {
let edn_str = chars_to_string(edn);
let brcode: BrCode = edn_rs::from_str(&edn_str).unwrap();
let svg = brcode.to_svg_standard_string();

to_c_char(&svg)
}

#[no_mangle]
pub extern "C" fn edn_to_svg_file(edn: *const c_char, file_path: *const c_char) {
let edn_str = chars_to_string(edn);
let file_path_str = chars_to_string(file_path);
let brcode: BrCode = edn_rs::from_str(&edn_str).unwrap();
brcode.to_standard_svg_file(&file_path_str);
}

// Json
#[no_mangle]
pub extern "C" fn json_from_brcode(json: *const c_char) -> *const c_char {
Expand All @@ -74,9 +92,26 @@ pub extern "C" fn json_from_brcode(json: *const c_char) -> *const c_char {
}

#[no_mangle]
pub extern "C" fn json_to_brcode(edn: *const c_char) -> *const c_char {
let edn_str = chars_to_string(edn);
let brcode: BrCode = serde_json::from_str(&edn_str).unwrap();
pub extern "C" fn json_to_brcode(json: *const c_char) -> *const c_char {
let json_str = chars_to_string(json);
let brcode: BrCode = serde_json::from_str(&json_str).unwrap();

to_c_char(&brcode_to_string(brcode))
}

#[no_mangle]
pub extern "C" fn json_to_svg_brcode(json: *const c_char) -> *const c_char {
let json_str = chars_to_string(json);
let brcode: BrCode = serde_json::from_str(&json_str).unwrap();
let svg = brcode.to_svg_standard_string();

to_c_char(&svg)
}

#[no_mangle]
pub extern "C" fn json_to_svg_file(json: *const c_char, file_path: *const c_char) {
let json_str = chars_to_string(json);
let file_path_str = chars_to_string(file_path);
let brcode: BrCode = serde_json::from_str(&json_str).unwrap();
brcode.to_standard_svg_file(&file_path_str);
}
40 changes: 40 additions & 0 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::aux::HashBrCode;
use crate::parse::Data;
use edn_derive::{Deserialize, Serialize};
use serde_derive::{Deserialize as SerdeDeserialize, Serialize as SerdeSerialize};
use qrcode_generator::QrCodeEcc;

#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, SerdeDeserialize, SerdeSerialize)]
pub struct BrCode {
Expand Down Expand Up @@ -272,6 +273,39 @@ impl BrCode {
encode.push_str(&crc16);
encode
}

pub fn to_svg_string(&self, ecc: QrCodeEcc, size: usize) -> String {
let brcode = self.clone().encode();
let result: String = qrcode_generator::to_svg_to_string(&brcode.clone(), ecc, size, Some(brcode)).unwrap();
result
}

pub fn to_svg_standard_string(&self) -> String {
let brcode = self.clone().encode();
let result: String = qrcode_generator::to_svg_to_string(&brcode.clone(), QrCodeEcc::Low, 1024, Some(brcode)).unwrap();
result
}

pub fn to_vec_u8(&self, ecc: QrCodeEcc, size: usize) -> Vec<u8> {
let brcode = self.clone().encode();
let result = qrcode_generator::to_png_to_vec(&brcode, ecc, size).unwrap();
result
}

pub fn to_svg_file(&self, file_path: &str, ecc: QrCodeEcc, size: usize) {
let brcode = self.clone().encode();
qrcode_generator::to_svg_to_file(&brcode.clone(), ecc, size, Some(brcode), file_path).unwrap();
}

pub fn to_standard_svg_file(&self, file_path: &str) {
let brcode = self.clone().encode();
qrcode_generator::to_svg_to_file(&brcode.clone(), QrCodeEcc::Low, 1024, Some(brcode), file_path).unwrap();
}

pub fn to_png_file(&self, file_path: &str, ecc: QrCodeEcc, size: usize) {
let brcode = self.clone().encode();
qrcode_generator::to_png_to_file(&brcode.clone(), ecc, size, file_path).unwrap();
}
}

#[cfg(test)]
Expand All @@ -291,6 +325,12 @@ mod test {
assert_eq!(actual, expected);
}

#[test]
fn brcode_to_svg() {
let svg = expected().to_svg_standard_string();
assert_eq!(&svg[38..42], "<svg");
}

fn expected() -> BrCode {
BrCode {
payload_version: 1,
Expand Down

0 comments on commit e21e060

Please sign in to comment.