organicomplex 0.7.0

Interactive complex-valued cellular automaton on 2D and 3D grids in search of that stuff - emergence, open-endedness, organicity etc.
// use std::hash::Hash;

mod colors;
mod complex;
mod real;
mod rwbin;

pub use self::{
	colors::*,
	complex::*,
	real::*,
	rwbin::*
};

// ----------------------------------------------------------------

pub const BASE_DIR: &str = "_";

pub const JEXT: &str = "json";

pub const PROG_HOMEPAGE: &str = "https://sunkware.org/organicomplex";

pub const PROG_TITLE: &str = "OrganiComplex";

pub const PROG_VERSION: &str = env!("CARGO_PKG_VERSION"); // or option_env!() ? If compiling without Cargo, or the name of this variable changes...

// ----------------------------------------------------------------

pub trait PrependErrorString<T> {
	fn pre_err(self: Self, p: impl ToString) -> Result<T, String>;
}

impl<T, E: ToString> PrependErrorString<T> for Result<T, E> {
	/// Ok() result is not changed, while
	/// error-as-string "s" is prepended with given string "p" and colon:
	/// p: s
	fn pre_err(self: Self, p: impl ToString) -> Result<T, String> {
		match self {
			Ok(t) => Ok(t),
			Err(e) => Err(format!("{}: {}", p.to_string(), e.to_string()))
		}
	}
}

// ----------------------------------------------------------------
/*
pub trait Hash64 {
	fn hash64(self: &Self) -> u64;
}

impl<T: Hash> Hash64 for T {
	fn hash64(self: &Self) -> u64 {
		// from std::hash doc
		let mut hasher = DefaultHasher::new();
		self.hash(&mut hasher);
		hasher.finish()
	}
}
*/
// ----------------------------------------------------------------

#[allow(dead_code)]
pub trait Elementruncable {
	fn elementruncated(&self, max_len: usize) -> Self;
}

impl Elementruncable for String {
	fn elementruncated(&self, max_len: usize) -> Self {
		let mut chars = self.chars();
		let mut s = String::new();
		let mut l: usize = 0;
		while let Some(ch) = chars.next() {
			if l < max_len {
				s.push(ch);
				l += 1;
			} else {
				break;
			}
		}
		s
	}
}

// ----------------------------------------------------------------

#[inline(always)]
#[allow(dead_code)]
pub fn binlog(mut n: i64) -> i32 {
    let mut bl: i32 = 0;
 	// Kind of binary search...
	if n > 0xFFFFFFFF {
		bl |= 0x20; n >>= 0x20;
	}
	if n > 0xFFFF {
		bl |= 0x10; n >>= 0x10;
	}
	if n > 0xFF {
		bl |= 8; n >>= 8;
	}
	if n > 0xF {
		bl |= 4; n >>= 4;
	}
	if n > 3 {
		bl |= 2; n >>= 2;
	}
	if n > 1 {
		bl |= 1;
	}
	bl
}

#[allow(dead_code)]
pub fn is_2pow(n: i64) -> bool { // is n = 2^m?
    (n & (n-1)) == 0
}

#[inline(always)]
#[allow(dead_code)]
pub fn scale_u8(lum: u8, mult: i64, max_mult_binlog: i32) -> u8 {
	(((lum as i64) * mult) >> max_mult_binlog) as u8
}

// ----------------------------------------------------------------