Skip to content

Commit

Permalink
Upstream merge (#5)
Browse files Browse the repository at this point in the history
Co-authored-by: aspen <luxx4x@protonmail.com>
Co-authored-by: ZeWaka <zewakagamer@gmail.com>
Co-authored-by: Jared-Fogle <35135081+Jared-Fogle@users.noreply.github.com>
Co-authored-by: Tad Hardesty <tad@platymuus.com>
Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
  • Loading branch information
6 people authored Oct 24, 2020
1 parent 8ebb99b commit 9a1bc1c
Show file tree
Hide file tree
Showing 14 changed files with 954 additions and 1,010 deletions.
1,456 changes: 665 additions & 791 deletions Cargo.lock

Large diffs are not rendered by default.

46 changes: 24 additions & 22 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rust-g"
edition = "2018"
version = "0.4.5"
version = "0.4.6"
authors = ["Bjorn Neergaard <bjorn@neersighted.com>"]
repository = "https://github.com/tgstation/rust-g"
license-file = "LICENSE"
Expand All @@ -12,37 +12,39 @@ crate-type = ["cdylib"]

[profile.release]
opt-level = 3
codegen-units = 1
lto = true

[dependencies]
failure = "0.1"
thiserror = "1.0"
flume = "0.9"
chrono = { version = "0.4", optional = true }
crypto-hash = { version = "0.3", optional = true }
hex = { version = "0.3", optional = true }
percent-encoding = { version = "1.0", optional = true }
url-dep = { version = "2.1.1", package = "url", optional = true }
png = { version = "0.11.0", optional = true }
git2 = { version = "0.7.1", optional = true, default-features = false }
noise = { version = "0.6.0", optional = true}
reqwest = { version = "0.9", optional = true, default-features = false, features = ["rustls-tls"] }
serde = { version = "1.0", optional = true }
md-5 = { version = "0.9", optional = true }
sha-1 = { version = "0.9", optional = true }
sha2 = { version = "0.9", optional = true }
hex = { version = "0.4", optional = true }
percent-encoding = { version = "2.1", optional = true }
url-dep = { version = "2.1", package = "url", optional = true }
png = { version = "0.16", optional = true }
git2 = { version = "0.13", optional = true, default-features = false }
noise = { version = "0.6", optional = true}
reqwest = { version = "0.10", optional = true, default-features = false, features = ["blocking", "rustls-tls"] }
serde = { version = "1.0", optional = true, features = ["derive"] }
serde_json = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true }
lazy_static = { version = "1.3", optional = true }
lazy_static = { version = "1.4", optional = true }
once_cell = { version = "1.4", optional = true }
mysql = { version = "20.0", optional = true }
dashmap = { version = "3.11", optional = true }

[dependencies.mysql]
version = "18.2"
optional = true
git = "https://github.com/blackbeam/rust-mysql-simple"
rev = "b039fe7a11609aeab9071289bcff496b9366389a"

[features]
default = ["dmi", "log", "git", "http", "sql", "noise"]
default = ["dmi", "log", "git", "http", "json", "sql", "noise"]
dmi = ["png"]
file = []
hash = ["crypto-hash", "hex"]
hash = ["md-5", "sha-1", "sha2", "hex"]
json = ["serde", "serde_json"]
log = ["chrono"]
url = ["url-dep", "percent-encoding"]
git = ["git2", "chrono"]
http = ["reqwest", "serde", "serde_json", "serde_derive", "lazy_static"]
sql = ["mysql", "serde", "serde_derive", "serde_json", "lazy_static"]
http = ["reqwest", "serde", "serde_json", "once_cell"]
sql = ["mysql", "serde", "serde_json", "once_cell", "dashmap"]
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ The [Rust] compiler:
# in the `rust-g` directory...
cd rust-g
# Linux
rustup override add stable-i686-unknown-linux-gnu
rustup target add i686-unknown-linux-gnu
# Windows
rustup override add stable-i686-pc-windows-msvc
rustup target add i686-pc-windows-msvc
```

System libraries:
Expand All @@ -61,7 +61,10 @@ compiling all Rust dependencies. The default configuration is suitable for
use with the [tgstation] codebase, but not [beestation]. To compile in release mode:

```sh
cargo build --release
# Linux
cargo build --release --target=i686-unknown-linux-gnu
# Windows
cargo build --release --target=i686-pc-windows-msvc
```

On Linux, the output will be `target/release/librust_g.so`.
Expand All @@ -71,7 +74,11 @@ On Windows, the output will be `target/release/rust_g.dll`.
For more advanced configuration, a list of modules may be passed:

```sh
cargo build --release --features dmi,file,log,url,http
export PKG_CONFIG_ALLOW_CROSS=1
# Linux
cargo build --release --target=i686-unknown-linux-gnu --features dmi,file,log,url,http
# Windows
cargo build --release --target=i686-pc-windows-msvc --features dmi,file,log,url,http
```

The default features are:
Expand All @@ -81,11 +88,11 @@ The default features are:
* git: Functions for robustly checking the current git revision.
* http: Asynchronous HTTP(s) client supporting most standard methods.
* sql: Asynchronous MySQL/MariaDB client library.
* noise: 2d Perlin noise.

Additional features are:
* noise: 2d Perlin noise.
* url: Faster replacements for `url_encode` and `url_decode`.
* file: Faster replacements for `file2text` and `text2file`.
* file: Faster replacements for `file2text` and `text2file`, as well as reading or checking if files exist.
* hash: Faster replacement for `md5`, support for SHA-1, SHA-256, and SHA-512. Requires OpenSSL on Linux.

## Installing
Expand Down
12 changes: 12 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ fn main() {
f,
r#"
#define rustg_file_read(fname) call(RUST_G, "file_read")(fname)
#define rustg_file_exists(fname) call(RUST_G, "file_exists")(fname)
#define rustg_file_write(text, fname) call(RUST_G, "file_write")(text, fname)
#define rustg_file_append(text, fname) call(RUST_G, "file_append")(text, fname)
Expand Down Expand Up @@ -123,6 +124,17 @@ fn main() {
"#).unwrap();
}

// module: json
if enabled!("JSON") {
write!(
f,
r#"
#define rustg_json_is_valid(text) (call(RUST_G, "json_is_valid")(text) == "true")
"#
)
.unwrap();
}

// module: log
if enabled!("LOG") {
write!(
Expand Down
9 changes: 5 additions & 4 deletions src/dmi.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::{Error, Result};
use png::{Decoder, Encoder, HasParameters, OutputInfo};
use png::{Decoder, Encoder, OutputInfo};
use std::{
fs::{create_dir_all, File},
path::Path,
Expand Down Expand Up @@ -28,7 +28,8 @@ fn read_png(path: &str) -> Result<(OutputInfo, Vec<u8>)> {

fn write_png(path: &str, info: OutputInfo, image: Vec<u8>) -> Result<()> {
let mut encoder = Encoder::new(File::create(path)?, info.width, info.height);
encoder.set(info.color_type).set(info.bit_depth);
encoder.set_color(info.color_type);
encoder.set_depth(info.bit_depth);

let mut writer = encoder.write_header()?;
Ok(writer.write_image_data(&image)?)
Expand Down Expand Up @@ -57,8 +58,8 @@ fn create_png(path: &str, width: &str, height: &str, data: &str) -> Result<()> {
}

let mut encoder = Encoder::new(File::create(path)?, width, height);
encoder.set(png::ColorType::RGB);
encoder.set(png::BitDepth::Eight);
encoder.set_color(png::ColorType::RGB);
encoder.set_depth(png::BitDepth::Eight);
let mut writer = encoder.write_header()?;
Ok(writer.write_image_data(&result)?)
}
95 changes: 27 additions & 68 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,93 +4,52 @@ use std::{
result,
str::Utf8Error,
};
use thiserror::Error;

#[cfg(feature = "png")]
use png::{DecodingError, EncodingError};

pub type Result<T> = result::Result<T, Error>;

#[derive(Fail, Debug)]
#[derive(Error, Debug)]
pub enum Error {
#[fail(display = "Illegal null character in string.")]
#[error("Illegal null character in string.")]
Null,
#[fail(display = "Invalid UTF-8 character at position {}.", _1)]
Utf8(#[cause] Utf8Error, usize),
#[fail(display = "Invalid or empty filename specified.")]
#[error("Invalid UTF-8 character at position {position}.")]
Utf8 { source: Utf8Error, position: usize },
#[error("Invalid or empty filename specified.")]
InvalidFilename,
#[fail(display = "{}", _0)]
Io(#[cause] io::Error),
#[fail(display = "Invalid algorithm specified.")]
#[error(transparent)]
Io(#[from] io::Error),
#[error("Invalid algorithm specified.")]
InvalidAlgorithm,
#[cfg(feature = "png")]
#[fail(display = "{}", _0)]
ImageDecoding(#[cause] DecodingError),
#[error(transparent)]
ImageDecoding(#[from] DecodingError),
#[cfg(feature = "png")]
#[fail(display = "{}", _0)]
ImageEncoding(#[cause] EncodingError),
#[fail(display = "{}", _0)]
ParseIntError(#[cause] ParseIntError),
#[fail(display = "{}", _0)]
ParseFloatError(#[cause] ParseFloatError),
#[error(transparent)]
ImageEncoding(#[from] EncodingError),
#[error(transparent)]
ParseIntError(#[from] ParseIntError),
#[error(transparent)]
ParseFloatError(#[from] ParseFloatError),
#[cfg(feature = "png")]
#[fail(display = "Invalid png data.")]
#[error("Invalid png data.")]
InvalidPngDataError,
#[cfg(feature = "http")]
#[fail(display = "{}", _0)]
RequestError(#[cause] reqwest::Error),
#[error(transparent)]
RequestError(#[from] reqwest::Error),
#[cfg(feature = "http")]
#[fail(display = "{}", _0)]
SerializationError(#[cause] serde_json::Error),
}

impl From<io::Error> for Error {
fn from(error: io::Error) -> Error {
Error::Io(error)
}
#[error(transparent)]
SerializationError(#[from] serde_json::Error),
}

impl From<Utf8Error> for Error {
fn from(error: Utf8Error) -> Error {
Error::Utf8(error, error.valid_up_to())
}
}

#[cfg(feature = "png")]
impl From<DecodingError> for Error {
fn from(error: DecodingError) -> Error {
Error::ImageDecoding(error)
}
}

#[cfg(feature = "png")]
impl From<EncodingError> for Error {
fn from(error: EncodingError) -> Error {
Error::ImageEncoding(error)
}
}

impl From<ParseIntError> for Error {
fn from(error: ParseIntError) -> Error {
Error::ParseIntError(error)
}
}

impl From<ParseFloatError> for Error {
fn from(error: ParseFloatError) -> Error {
Error::ParseFloatError(error)
}
}
#[cfg(feature = "http")]
impl From<reqwest::Error> for Error {
fn from(error: reqwest::Error) -> Error {
Error::RequestError(error)
}
}

#[cfg(feature = "http")]
impl From<serde_json::Error> for Error {
fn from(error: serde_json::Error) -> Error {
Error::SerializationError(error)
fn from(source: Utf8Error) -> Error {
Error::Utf8 {
source,
position: source.valid_up_to(),
}
}
}

Expand Down
34 changes: 28 additions & 6 deletions src/file.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use crate::error::Result;
use std::{
fs::{File, OpenOptions},
io::{Read, Write},
io::{BufReader, BufWriter, Read, Write},
};

byond_fn! { file_read(path) {
read(path).ok()
} }

byond_fn! { file_exists(path) {
Some(exists(path))
} }

byond_fn! { file_write(data, path) {
write(data, path).err()
} }
Expand All @@ -17,8 +21,9 @@ byond_fn! { file_append(data, path) {
} }

fn read(path: &str) -> Result<String> {
let mut file = File::open(path)?;
let file = File::open(path)?;
let metadata = file.metadata()?;
let mut file = BufReader::new(file);

let mut content = String::with_capacity(metadata.len() as usize);
file.read_to_string(&mut content)?;
Expand All @@ -27,15 +32,26 @@ fn read(path: &str) -> Result<String> {
Ok(content)
}

fn exists(path: &str) -> String {
let path = std::path::Path::new(path);
path.exists().to_string()
}

fn write(data: &str, path: &str) -> Result<usize> {
let path: &std::path::Path = path.as_ref();
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}

let mut file = File::create(path)?;
let mut file = BufWriter::new(File::create(path)?);
let written = file.write(data.as_bytes())?;

file.flush()?;
file.into_inner()
.map_err(|e| std::io::Error::new(e.error().kind(), e.error().to_string()))? // This is god-awful, but the compiler REFUSES to let me get an owned copy of `e`
.sync_all()?;

Ok(file.write(data.as_bytes())?)
Ok(written)
}

fn append(data: &str, path: &str) -> Result<usize> {
Expand All @@ -44,7 +60,13 @@ fn append(data: &str, path: &str) -> Result<usize> {
std::fs::create_dir_all(parent)?;
}

let mut file = OpenOptions::new().append(true).create(true).open(path)?;
let mut file = BufWriter::new(OpenOptions::new().append(true).create(true).open(path)?);
let written = file.write(data.as_bytes())?;

file.flush()?;
file.into_inner()
.map_err(|e| std::io::Error::new(e.error().kind(), e.error().to_string()))?
.sync_all()?;

Ok(file.write(data.as_bytes())?)
Ok(written)
}
Loading

0 comments on commit 9a1bc1c

Please sign in to comment.