start of logtail package

Signed-off-by: Christine Dodrill <me@christine.website>
This commit is contained in:
Cadey Ratio 2021-08-24 18:40:57 -04:00
parent dec722918c
commit 03d700bdb6
7 changed files with 300 additions and 4 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
eval "$(lorri direnv)"

4
.gitignore vendored
View File

@ -4,10 +4,6 @@
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk

161
Cargo.lock generated Normal file
View File

@ -0,0 +1,161 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cpufeatures"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef"
dependencies = [
"libc",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
]
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "libc"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5"
[[package]]
name = "logtail"
version = "0.1.0"
dependencies = [
"hex",
"rand",
"sha2",
]
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "sha2"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12"
dependencies = [
"block-buffer",
"cfg-if",
"cpufeatures",
"digest",
"opaque-debug",
]
[[package]]
name = "typenum"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

2
Cargo.toml Normal file
View File

@ -0,0 +1,2 @@
[workspace]
members = ["crates/*"]

11
crates/logtail/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "logtail"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
hex = "0.4"
rand = "0"
sha2 = "0.9"

115
crates/logtail/src/lib.rs Normal file
View File

@ -0,0 +1,115 @@
use sha2::{Digest, Sha256};
use std::fmt;
/// This represents an instance that write logs.
/// Private IDs are only shared with the server when writing logs.
#[derive(Clone, PartialEq, Eq)]
pub struct PrivateID([u8; SHA256_SIZE]);
impl PrivateID {
/// Safely generate a new PrivateId for use in Config objects.
/// You should persist this across runs of an instance of your app, so that
/// it can append to the same log file on each run.
pub fn new() -> Self {
let mut id: [u8; 32] = rand::random();
id[0] &= 248;
id[31] = (id[31] & 127) | 64;
Self(id)
}
/// Parse a PrivateID from its base 16 representation.
pub fn from_hex(data: String) -> Result<Self, hex::FromHexError> {
let mut id: [u8; 32] = [0; 32];
hex::decode_to_slice(data, &mut id)?;
Ok(Self(id))
}
/// Show a private ID as its base 16 representation.
pub fn as_hex(&self) -> String {
hex::encode(self.0)
}
pub fn as_public(&self) -> PublicID {
let mut hasher = Sha256::new();
hasher.update(&self.0);
PublicID(hasher.finalize().into())
}
}
impl fmt::Display for PrivateID {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.as_hex())
}
}
impl fmt::Debug for PrivateID {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "PrivateID({})", self.as_hex())
}
}
const SHA256_SIZE: usize = 32;
#[derive(Clone, PartialEq, Eq)]
pub struct PublicID([u8; SHA256_SIZE]);
impl PublicID {
/// Parse a PublicID from its base 16 representation.
pub fn from_hex(data: String) -> Result<Self, hex::FromHexError> {
let mut id: [u8; 32] = [0; 32];
hex::decode_to_slice(data, &mut id)?;
Ok(Self(id))
}
/// Show a public ID as its base 16 representation.
pub fn as_hex(&self) -> String {
hex::encode(self.0)
}
}
impl fmt::Display for PublicID {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.as_hex())
}
}
impl fmt::Debug for PublicID {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "PublicID({})", self.as_hex())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn id() {
let id = PrivateID::new();
assert_ne!(id.as_hex(), "".to_string());
}
#[test]
fn encode_decode() {
let id = PrivateID::new();
let as_hex = id.as_hex();
let other_id = PrivateID::from_hex(as_hex).unwrap();
assert_eq!(id, other_id);
}
#[test]
fn to_public() {
let id = PrivateID::from_hex(
"6451f1641112c13e80daa7237d62391b028e638fef9cf91fd7ea347a5290a643".to_string(),
)
.unwrap();
let pub_id = id.as_public();
assert_eq!(
pub_id,
PublicID::from_hex(
"db3a35df70555653e5fcff5bbc06e1573ad67e00744b56691c15cde72d17c449".to_string()
)
.unwrap()
);
}
}

10
shell.nix Normal file
View File

@ -0,0 +1,10 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
rustc cargo rust-analyzer rustfmt
# keep this line if you use bash
bashInteractive
];
}