<commit_before>/*!
Rich Structure.
 */

// References:
//
// * https://github.com/dishather/richprint
// * https://ntcore.com/?p=27
// * https://securelist.com/the-devils-in-the-rich-header/84348/
// * http://bytepointer.com/articles/the_microsoft_rich_header.htm
// * http://bytepointer.com/articles/rich_header_lifewire_vxmags_29A-8.009.htm
// * https://pdfs.semanticscholar.org/44ad/fa896e6598b1723507060126125a0cad39a1.pdf

use std::{fmt, iter, mem, result, slice};

use {Error, Result};
use super::{Pe};

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

// The Rich structure:
// 'DanS' ^ x, x, x, x,
// compid ^ x, revision ^ x, ...
// 'Rich', x
// padding, ...

const DANS_MARKER: u32 = 0x536e6144; // "DanS"
const RICH_MARKER: u32 = 0x68636952; // "Rich"

/// Rich structure.
#[derive(Copy, Clone)]
pub struct RichStructure<'a> {
	dos_stub: &'a [u32],
	image: &'a [u32],
}
impl<'a> RichStructure<'a> {
	pub(crate) fn try_from<P: Pe<'a> + Copy>(pe: P) -> Result<RichStructure<'a>> {
		let dos_header = pe.dos_header();

		// Read as a slice of dwords up until the PE headers
		let len = (dos_header.e_lfanew / 4) as usize;
		let image = unsafe { slice::from_raw_parts(dos_header as *const _ as *const u32, len) };

		// Skip the padding zeroes
		let mut end = image.len();
		loop {
			if end < 16 {
				return Err(Error::Invalid);
			}
			if image[end - 1] != 0 {
				break;
			}
			end -= 1;
		}
		let end = end;

		// Find the Rich marker and the xor key
		if image[end - 2] != RICH_MARKER {
			return Err(Error::BadMagic);
		}
		let x = image[end - 1];
		let dx = DANS_MARKER ^ x;

		// Scan to find the header block
		let mut start = end - 6;
		loop {
			if start < 16 {
				return Err(Error::Invalid);
			}
			if image[start] == dx && image[start + 1] == x && image[start + 2] == x && image[start + 3] == x {
				break;
			}
			start -= 2;
		}
		let start = start;

		// Everything before is the dos stub
		let dos_stub = &image[..start];
		let image = &image[start..end];

		Ok(RichStructure { dos_stub, image })
	}
	/// Returns the Rich image without the padding.
	pub fn image(&self) -> &'a [u32] {
		self.image
	}
	/// Calculate the checksum.
	///
	/// The checksum should be equal to the xor key.
	pub fn checksum(&self) -> u32 {
		Self::_checksum(self.dos_stub, self.records())
	}
	fn _checksum<I>(dos_stub: &[u32], records: I) -> u32 where I: Iterator<Item = RichRecord> {
		let mut csum = mem::size_of_val(dos_stub) as u32;

		let mut i = 0;
		for dword in dos_stub {
			// Zero the e_lfanew field
			let bytes = if i == 0x3c { [0; 4] }
			else { unsafe { *(dword as *const _ as *const [u8; 4]) } };
			// Accumulate
			csum = u32::wrapping_add(csum, (bytes[0] as u32).rotate_left(i + 0));
			csum = u32::wrapping_add(csum, (bytes[1] as u32).rotate_left(i + 1));
			csum = u32::wrapping_add(csum, (bytes[2] as u32).rotate_left(i + 2));
			csum = u32::wrapping_add(csum, (bytes[3] as u32).rotate_left(i + 3));
			i += 4;
		}

		for record in records {
			let value = (record.product as u32) << 16 | (record.build as u32);
			csum = u32::wrapping_add(csum, value.rotate_left(record.count));
		}

		csum
	}
	/// Gets the xor key.
	pub fn xor_key(&self) -> u32 {
		self.image[1]
	}
	/// Gets the records.
	pub fn records(&self) -> RichIter<'a> {
		let iter = &self.image[4..self.image.len() - 2];
		let key = self.xor_key();
		RichIter { iter, key }
	}
	/// Encodes a new set of records.
	///
	/// If the destination does not have the right len, returns Err with the right len.
	/// Call encode again with destination of the returned len, destination is not modified.
	///
	/// Returns Ok with the len of the destination when encoding was successful.
	pub fn encode(&self, records: &[RichRecord], dest: &mut [u32]) -> result::Result<usize, usize> {
		let xor_key = Self::_checksum(self.dos_stub, records.iter().cloned());
		let n = records.len();
		let total_size = ((xor_key / 32) % 3 + n as u32) * 8 + 0x20;
		let total_len = (total_size / 4) as usize;
		if dest.len() < n * 2 + 6 {
			Err(total_len)
		}
		else {
			// Write the header
			dest[0] = DANS_MARKER ^ xor_key;
			dest[1] = xor_key;
			dest[2] = xor_key;
			dest[3] = xor_key;
			// Write the records
			for (i, record) in records.iter().enumerate() {
				let values = record.encode(xor_key);
				dest[i * 2 + 4] = values[0];
				dest[i * 2 + 5] = values[1];
			}
			// Write the footer
			dest[n * 2 + 4] = RICH_MARKER;
			dest[n * 2 + 5] = xor_key;
			// Write the padding
			for i in n * 2 + 6..dest.len() {
				dest[i] = 0;
			}
			Ok(total_len)
		}
	}
}
impl<'a> fmt::Debug for RichStructure<'a> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.debug_struct("RichStructure")
			.field("xor_key", &self.xor_key())
			.field("checksum", &self.checksum())
			.field("records", &self.records())
			.finish()
	}
}

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

/// Rich record.
///
/// Rich records contain a product identifier and its build number.
/// The count value indicates how many .obj files were linked generated by the product.
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
#[repr(C)]
pub struct RichRecord {
	pub build: u16,
	pub product: u16,
	pub count: u32,
}
impl RichRecord {
	/// Decodes the record with the given key.
	pub fn decode(key: u32, values: &[u32; 2]) -> RichRecord {
		let field = values[0] ^ key;
		let build = (field & 0xffff) as u16;
		let product = ((field >> 16) & 0xffff) as u16;
		let count = values[1] ^ key;
		RichRecord { build, product, count }
	}
	/// Encodes the record with the given key.
	pub fn encode(&self, key: u32) -> [u32; 2] {
		let value = (self.product as u32) << 16 | (self.build as u32);
		[value ^ key, self.count ^ key]
	}
}

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

/// Iterator over the Rich records.
#[derive(Clone)]
pub struct RichIter<'a> {
	iter: &'a [u32],
	key: u32,
}
impl<'a> Iterator for RichIter<'a> {
	type Item = RichRecord;
	fn next(&mut self) -> Option<RichRecord> {
		if self.iter.len() >= 2 {
			let record = RichRecord::decode(self.key, &[self.iter[0], self.iter[1]]);
			self.iter = &self.iter[2..];
			Some(record)
		}
		else {
			None
		}
	}
	fn size_hint(&self) -> (usize, Option<usize>) {
		let len = self.iter.len() / 2;
		(len, Some(len))
	}
	fn count(self) -> usize {
		self.size_hint().0
	}
	fn nth(&mut self, n: usize) -> Option<RichRecord> {
		if self.iter.len() >= n * 2 + 2 {
			let record = RichRecord::decode(self.key, &[self.iter[n * 2], self.iter[n * 2 + 1]]);
			self.iter = &self.iter[n * 2 + 2..];
			Some(record)
		}
		else {
			self.iter = &self.iter[..0];
			None
		}
	}
}
impl<'a> DoubleEndedIterator for RichIter<'a> {
	fn next_back(&mut self) -> Option<RichRecord> {
		let len = self.iter.len();
		if len >= 2 {
			let record = RichRecord::decode(self.key, &[self.iter[len - 2], self.iter[len - 1]]);
			self.iter = &self.iter[..len - 2];
			Some(record)
		}
		else {
			None
		}
	}
}
impl<'a> ExactSizeIterator for RichIter<'a> {}
impl<'a> iter::FusedIterator for RichIter<'a> {}
impl<'a> fmt::Debug for RichIter<'a> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.debug_list().entries(self.clone()).finish()
	}
}

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

/*
	"rich_structure": {
		"xor_key": 129284757318,
		"checksum": 129284757318,
		"records": [
			{
				"build": 6030,
				"product": 95,
				"count": 68,
			},
		]
	},
*/

#[cfg(feature = "serde")]
mod serde {
	use util::serde_helper::*;
	use super::RichStructure;

	impl<'a> Serialize for RichStructure<'a> {
		fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
			let mut state = serializer.serialize_struct("RichStructure", 3)?;
			state.serialize_field("xor_key", &self.xor_key())?;
			state.serialize_field("checksum", &self.checksum())?;
			state.serialize_field("records", &SerdeIter(self.records()))?;
			state.end()
		}
	}
}

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

#[cfg(test)]
pub(crate) fn test<'a, P: 'a + Pe<'a> + Copy>(pe: P) -> Result<()> {
	let rich_structure = pe.rich_structure()?;
	let _checksum = rich_structure.checksum();

	let records: Vec<_> = rich_structure.records().collect();
	let mut encoded = vec![0u32; rich_structure.image().len()];
	let _ = rich_structure.encode(&records, &mut encoded);

	Ok(())
}
<commit_msg>Rich structure Object kind (#120)<commit_after>/*!
Rich Structure.
 */

// References:
//
// * https://github.com/dishather/richprint
// * https://ntcore.com/?p=27
// * https://securelist.com/the-devils-in-the-rich-header/84348/
// * http://bytepointer.com/articles/the_microsoft_rich_header.htm
// * http://bytepointer.com/articles/rich_header_lifewire_vxmags_29A-8.009.htm
// * https://pdfs.semanticscholar.org/44ad/fa896e6598b1723507060126125a0cad39a1.pdf

use std::{fmt, iter, mem, result, slice};

use {Error, Result};
use super::{Pe};

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

// The Rich structure:
// 'DanS' ^ x, x, x, x,
// compid ^ x, revision ^ x, ...
// 'Rich', x
// padding, ...

const DANS_MARKER: u32 = 0x536e6144; // "DanS"
const RICH_MARKER: u32 = 0x68636952; // "Rich"

/// Rich structure.
#[derive(Copy, Clone)]
pub struct RichStructure<'a> {
	dos_stub: &'a [u32],
	image: &'a [u32],
}
impl<'a> RichStructure<'a> {
	pub(crate) fn try_from<P: Pe<'a> + Copy>(pe: P) -> Result<RichStructure<'a>> {
		let dos_header = pe.dos_header();

		// Read as a slice of dwords up until the PE headers
		let len = (dos_header.e_lfanew / 4) as usize;
		let image = unsafe { slice::from_raw_parts(dos_header as *const _ as *const u32, len) };

		// Skip the padding zeroes
		let mut end = image.len();
		loop {
			if end < 16 {
				return Err(Error::Invalid);
			}
			if image[end - 1] != 0 {
				break;
			}
			end -= 1;
		}
		let end = end;

		// Find the Rich marker and the xor key
		if image[end - 2] != RICH_MARKER {
			return Err(Error::BadMagic);
		}
		let x = image[end - 1];
		let dx = DANS_MARKER ^ x;

		// Scan to find the header block
		let mut start = end - 6;
		loop {
			if start < 16 {
				return Err(Error::Invalid);
			}
			if image[start] == dx && image[start + 1] == x && image[start + 2] == x && image[start + 3] == x {
				break;
			}
			start -= 2;
		}
		let start = start;

		// Everything before is the dos stub
		let dos_stub = &image[..start];
		let image = &image[start..end];

		Ok(RichStructure { dos_stub, image })
	}
	/// Returns the Rich image without the padding.
	pub fn image(&self) -> &'a [u32] {
		self.image
	}
	/// Calculate the checksum.
	///
	/// The checksum should be equal to the xor key.
	pub fn checksum(&self) -> u32 {
		Self::_checksum(self.dos_stub, self.records())
	}
	fn _checksum<I>(dos_stub: &[u32], records: I) -> u32 where I: Iterator<Item = RichRecord> {
		let mut csum = mem::size_of_val(dos_stub) as u32;

		let mut i = 0;
		for dword in dos_stub {
			// Zero the e_lfanew field
			let bytes = if i == 0x3c { [0; 4] }
			else { unsafe { *(dword as *const _ as *const [u8; 4]) } };
			// Accumulate
			csum = u32::wrapping_add(csum, (bytes[0] as u32).rotate_left(i + 0));
			csum = u32::wrapping_add(csum, (bytes[1] as u32).rotate_left(i + 1));
			csum = u32::wrapping_add(csum, (bytes[2] as u32).rotate_left(i + 2));
			csum = u32::wrapping_add(csum, (bytes[3] as u32).rotate_left(i + 3));
			i += 4;
		}

		for record in records {
			let value = (record.product as u32) << 16 | (record.build as u32);
			csum = u32::wrapping_add(csum, value.rotate_left(record.count));
		}

		csum
	}
	/// Gets the xor key.
	pub fn xor_key(&self) -> u32 {
		self.image[1]
	}
	/// Gets the records.
	pub fn records(&self) -> RichIter<'a> {
		let iter = &self.image[4..self.image.len() - 2];
		let key = self.xor_key();
		RichIter { iter, key }
	}
	/// Encodes a new set of records.
	///
	/// If the destination does not have the right len, returns Err with the right len.
	/// Call encode again with destination of the returned len, destination is not modified.
	///
	/// Returns Ok with the len of the destination when encoding was successful.
	pub fn encode(&self, records: &[RichRecord], dest: &mut [u32]) -> result::Result<usize, usize> {
		let xor_key = Self::_checksum(self.dos_stub, records.iter().cloned());
		let n = records.len();
		let total_size = ((xor_key / 32) % 3 + n as u32) * 8 + 0x20;
		let total_len = (total_size / 4) as usize;
		if dest.len() < n * 2 + 6 {
			Err(total_len)
		}
		else {
			// Write the header
			dest[0] = DANS_MARKER ^ xor_key;
			dest[1] = xor_key;
			dest[2] = xor_key;
			dest[3] = xor_key;
			// Write the records
			for (i, record) in records.iter().enumerate() {
				let values = record.encode(xor_key);
				dest[i * 2 + 4] = values[0];
				dest[i * 2 + 5] = values[1];
			}
			// Write the footer
			dest[n * 2 + 4] = RICH_MARKER;
			dest[n * 2 + 5] = xor_key;
			// Write the padding
			for i in n * 2 + 6..dest.len() {
				dest[i] = 0;
			}
			Ok(total_len)
		}
	}
}
impl<'a> fmt::Debug for RichStructure<'a> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.debug_struct("RichStructure")
			.field("xor_key", &self.xor_key())
			.field("checksum", &self.checksum())
			.field("records", &self.records())
			.finish()
	}
}

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

/// Rich record.
///
/// Rich records contain a product identifier and its build number.
/// The count value indicates how many .obj files were linked generated by the product.
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
#[repr(C)]
pub struct RichRecord {
	pub build: u16,
	pub product: u16,
	pub count: u32,
}
impl RichRecord {
	/// Decodes the record with the given key.
	pub fn decode(key: u32, values: &[u32; 2]) -> RichRecord {
		let field = values[0] ^ key;
		let build = (field & 0xffff) as u16;
		let product = ((field >> 16) & 0xffff) as u16;
		let count = values[1] ^ key;
		RichRecord { build, product, count }
	}
	/// Encodes the record with the given key.
	pub fn encode(&self, key: u32) -> [u32; 2] {
		let value = (self.product as u32) << 16 | (self.build as u32);
		[value ^ key, self.count ^ key]
	}
}

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

/// Defines the kinds of objects.
///
/// Rich records can identify the product used and with it the _'language'_ of the objects.
/// This allows a mapping of products and the kind of _'language'_ it was generated from.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub enum ObjectKind {
	Unknown,
	Link,
	/// Exported symbol.
	Export,
	/// Imported symbol.
	Import,
	/// Resource object.
	Resource,
	/// Assembly object.
	Assembly,
	/// C++ object.
	#[cfg_attr(feature = "serde", serde(rename = "C++"))]
	CPP,
	/// C object.
	C,
}
impl From<u16> for ObjectKind {
	fn from(product: u16) -> ObjectKind {
		match product {
			0x00ff          | 0x00c9 | 0x009a          | 0x007c | 0x005e | 0x0045          | 0x0006 => ObjectKind::Resource,
			0x0100 | 0x00dc | 0x00ca | 0x009b | 0x0092 | 0x007a | 0x005c | 0x003f                   => ObjectKind::Export,
			0x0101 | 0x00dd | 0x00cb | 0x009c | 0x0093 | 0x007b | 0x005d | 0x0019          | 0x0002 => ObjectKind::Import,
			0x0102 | 0x00de | 0x00cc | 0x009d | 0x0091 | 0x0078 | 0x005a | 0x003d          | 0x0004 => ObjectKind::Link,
			0x0103 | 0x00df | 0x00cd | 0x009e | 0x0095 | 0x007d | 0x000f | 0x0040                   => ObjectKind::Assembly,
			0x0104 | 0x00e0 | 0x00ce | 0x00aa | 0x0083 | 0x006d | 0x005f | 0x001c | 0x000a | 0x0015 => ObjectKind::C,
			0x0105 | 0x00e1 | 0x00cf | 0x00ab | 0x0084 | 0x006e | 0x0060 | 0x001d | 0x000b | 0x0016 => ObjectKind::CPP,

			0x0001 => ObjectKind::Import,
			_ => ObjectKind::Unknown,
		}
	}
}

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

/// Iterator over the Rich records.
#[derive(Clone)]
pub struct RichIter<'a> {
	iter: &'a [u32],
	key: u32,
}
impl<'a> Iterator for RichIter<'a> {
	type Item = RichRecord;
	fn next(&mut self) -> Option<RichRecord> {
		if self.iter.len() >= 2 {
			let record = RichRecord::decode(self.key, &[self.iter[0], self.iter[1]]);
			self.iter = &self.iter[2..];
			Some(record)
		}
		else {
			None
		}
	}
	fn size_hint(&self) -> (usize, Option<usize>) {
		let len = self.iter.len() / 2;
		(len, Some(len))
	}
	fn count(self) -> usize {
		self.size_hint().0
	}
	fn nth(&mut self, n: usize) -> Option<RichRecord> {
		if self.iter.len() >= n * 2 + 2 {
			let record = RichRecord::decode(self.key, &[self.iter[n * 2], self.iter[n * 2 + 1]]);
			self.iter = &self.iter[n * 2 + 2..];
			Some(record)
		}
		else {
			self.iter = &self.iter[..0];
			None
		}
	}
}
impl<'a> DoubleEndedIterator for RichIter<'a> {
	fn next_back(&mut self) -> Option<RichRecord> {
		let len = self.iter.len();
		if len >= 2 {
			let record = RichRecord::decode(self.key, &[self.iter[len - 2], self.iter[len - 1]]);
			self.iter = &self.iter[..len - 2];
			Some(record)
		}
		else {
			None
		}
	}
}
impl<'a> ExactSizeIterator for RichIter<'a> {}
impl<'a> iter::FusedIterator for RichIter<'a> {}
impl<'a> fmt::Debug for RichIter<'a> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		f.debug_list().entries(self.clone()).finish()
	}
}

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

/*
	"rich_structure": {
		"xor_key": 129284757318,
		"checksum": 129284757318,
		"records": [
			{
				"build": 6030,
				"product": 95,
				"count": 68,
			},
		]
	},
*/

#[cfg(feature = "serde")]
mod serde {
	use util::serde_helper::*;
	use super::{RichStructure, RichRecord, ObjectKind};

	impl<'a> Serialize for RichStructure<'a> {
		fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
			let mut state = serializer.serialize_struct("RichStructure", 3)?;
			state.serialize_field("xor_key", &self.xor_key())?;
			state.serialize_field("checksum", &self.checksum())?;
			state.serialize_field("records", &SerdeIter(self.records()))?;
			state.end()
		}
	}
	impl Serialize for RichRecord {
		fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
			let mut state = serializer.serialize_struct("RichRecrod", 4)?;
			state.serialize_field("product", &self.product)?;
			state.serialize_field("kind", &ObjectKind::from(self.product))?;
			state.serialize_field("build", &self.build)?;
			state.serialize_field("count", &self.count)?;
			state.end()
		}
	}
}

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

#[cfg(test)]
pub(crate) fn test<'a, P: 'a + Pe<'a> + Copy>(pe: P) -> Result<()> {
	let rich_structure = pe.rich_structure()?;
	let _checksum = rich_structure.checksum();

	let records: Vec<_> = rich_structure.records().collect();
	let mut encoded = vec![0u32; rich_structure.image().len()];
	let _ = rich_structure.encode(&records, &mut encoded);

	Ok(())
}
<|endoftext|>


<commit_before>pub mod token;
pub mod sub;
pub mod unescaped_text;
mod num_format;
<commit_msg>refactor/polish ~ fix `cargo clippy` complaints (allow module_inception)<commit_after>pub mod token;
pub mod sub;
pub mod unescaped_text;
#[allow(clippy::module_inception)]
mod num_format;
<|endoftext|>


<commit_before>use crate::colors::{BitDepth, ColorType};
use crate::headers::IhdrData;
use crate::png::PngImage;
use bit_vec::BitVec;

const ONE_BIT_PERMUTATIONS: [u8; 2] = [0b0000_0000, 0b1111_1111];
const TWO_BIT_PERMUTATIONS: [u8; 4] = [0b0000_0000, 0b0101_0101, 0b1010_1010, 0b1111_1111];
const FOUR_BIT_PERMUTATIONS: [u8; 16] = [
    0b0000_0000,
    0b0001_0001,
    0b0010_0010,
    0b0011_0011,
    0b0100_0100,
    0b0101_0101,
    0b0110_0110,
    0b0111_0111,
    0b1000_1000,
    0b1001_1001,
    0b1010_1010,
    0b1011_1011,
    0b1100_1100,
    0b1101_1101,
    0b1110_1110,
    0b1111_1111,
];

/// Attempt to reduce the bit depth of the image
/// Returns true if the bit depth was reduced, false otherwise
#[must_use]
pub fn reduce_bit_depth(png: &PngImage, minimum_bits: usize) -> Option<PngImage> {
    if png.ihdr.bit_depth != BitDepth::Sixteen {
        if png.ihdr.color_type == ColorType::Indexed || png.ihdr.color_type == ColorType::Grayscale
        {
            return reduce_bit_depth_8_or_less(png, minimum_bits);
        }
        return None;
    }

    // Reduce from 16 to 8 bits per channel per pixel
    let mut reduced = Vec::with_capacity(
        (png.ihdr.width * png.ihdr.height * u32::from(png.channels_per_pixel()) + png.ihdr.height)
            as usize,
    );
    let mut high_byte = 0;

    for line in png.scan_lines() {
        reduced.push(line.filter);
        for (i, &byte) in line.data.iter().enumerate() {
            if i % 2 == 0 {
                // High byte
                high_byte = byte;
            } else {
                // Low byte
                if high_byte != byte {
                    // Can't reduce, exit early
                    return None;
                }
                reduced.push(byte);
            }
        }
    }

    Some(PngImage {
        data: reduced,
        ihdr: IhdrData {
            bit_depth: BitDepth::Eight,
            ..png.ihdr
        },
        palette: None,
        transparency_pixel: png.transparency_pixel.clone(),
        aux_headers: png.aux_headers.clone(),
    })
}

#[must_use]
pub fn reduce_bit_depth_8_or_less(png: &PngImage, mut minimum_bits: usize) -> Option<PngImage> {
    assert!(minimum_bits >= 1 && minimum_bits < 8);
    let mut reduced = BitVec::with_capacity(png.data.len() * 8);
    let bit_depth: usize = png.ihdr.bit_depth.as_u8() as usize;
    if minimum_bits >= bit_depth {
        return None;
    }
    for line in png.scan_lines() {
        if png.ihdr.color_type == ColorType::Indexed {
            let line_max = line
                .data
                .iter()
                .map(|&byte| match png.ihdr.bit_depth {
                    BitDepth::Two => (byte & 0x3)
                        .max((byte >> 2) & 0x3)
                        .max((byte >> 4) & 0x3)
                        .max(byte >> 6),
                    BitDepth::Four => (byte & 0xF).max(byte >> 4),
                    _ => byte,
                })
                .max()
                .unwrap_or(0);
            let required_bits = match line_max {
                x if x > 0x0F => 8,
                x if x > 0x03 => 4,
                x if x > 0x01 => 2,
                _ => 1,
            };
            if required_bits > minimum_bits {
                minimum_bits = required_bits;
                if minimum_bits >= bit_depth {
                    // Not reducable
                    return None;
                }
            }
        } else {
            let bit_vec = BitVec::from_bytes(&line.data);
            for byte in bit_vec.to_bytes() {
                while minimum_bits < bit_depth {
                    let permutations: &[u8] = if minimum_bits == 1 {
                        &ONE_BIT_PERMUTATIONS
                    } else if minimum_bits == 2 {
                        &TWO_BIT_PERMUTATIONS
                    } else if minimum_bits == 4 {
                        &FOUR_BIT_PERMUTATIONS
                    } else {
                        return None;
                    };
                    if permutations.iter().any(|perm| *perm == byte) {
                        break;
                    } else {
                        minimum_bits <<= 1;
                    }
                }
            }
        }
    }

    for line in png.scan_lines() {
        reduced.extend(BitVec::from_bytes(&[line.filter]));
        let bit_vec = BitVec::from_bytes(&line.data);
        for (i, bit) in bit_vec.iter().enumerate() {
            let bit_index = bit_depth - (i % bit_depth);
            if bit_index <= minimum_bits {
                reduced.push(bit);
            }
        }
        // Pad end of line to get 8 bits per byte
        while reduced.len() % 8 != 0 {
            reduced.push(false);
        }
    }

    Some(PngImage {
        data: reduced.to_bytes(),
        ihdr: IhdrData {
            bit_depth: BitDepth::from_u8(minimum_bits as u8),
            ..png.ihdr
        },
        aux_headers: png.aux_headers.clone(),
        palette: png.palette.clone(),
        transparency_pixel: png.transparency_pixel.clone(),
    })
}
<commit_msg>Fix a new clippy lint<commit_after>use crate::colors::{BitDepth, ColorType};
use crate::headers::IhdrData;
use crate::png::PngImage;
use bit_vec::BitVec;

const ONE_BIT_PERMUTATIONS: [u8; 2] = [0b0000_0000, 0b1111_1111];
const TWO_BIT_PERMUTATIONS: [u8; 4] = [0b0000_0000, 0b0101_0101, 0b1010_1010, 0b1111_1111];
const FOUR_BIT_PERMUTATIONS: [u8; 16] = [
    0b0000_0000,
    0b0001_0001,
    0b0010_0010,
    0b0011_0011,
    0b0100_0100,
    0b0101_0101,
    0b0110_0110,
    0b0111_0111,
    0b1000_1000,
    0b1001_1001,
    0b1010_1010,
    0b1011_1011,
    0b1100_1100,
    0b1101_1101,
    0b1110_1110,
    0b1111_1111,
];

/// Attempt to reduce the bit depth of the image
/// Returns true if the bit depth was reduced, false otherwise
#[must_use]
pub fn reduce_bit_depth(png: &PngImage, minimum_bits: usize) -> Option<PngImage> {
    if png.ihdr.bit_depth != BitDepth::Sixteen {
        if png.ihdr.color_type == ColorType::Indexed || png.ihdr.color_type == ColorType::Grayscale
        {
            return reduce_bit_depth_8_or_less(png, minimum_bits);
        }
        return None;
    }

    // Reduce from 16 to 8 bits per channel per pixel
    let mut reduced = Vec::with_capacity(
        (png.ihdr.width * png.ihdr.height * u32::from(png.channels_per_pixel()) + png.ihdr.height)
            as usize,
    );
    let mut high_byte = 0;

    for line in png.scan_lines() {
        reduced.push(line.filter);
        for (i, &byte) in line.data.iter().enumerate() {
            if i % 2 == 0 {
                // High byte
                high_byte = byte;
            } else {
                // Low byte
                if high_byte != byte {
                    // Can't reduce, exit early
                    return None;
                }
                reduced.push(byte);
            }
        }
    }

    Some(PngImage {
        data: reduced,
        ihdr: IhdrData {
            bit_depth: BitDepth::Eight,
            ..png.ihdr
        },
        palette: None,
        transparency_pixel: png.transparency_pixel.clone(),
        aux_headers: png.aux_headers.clone(),
    })
}

#[must_use]
pub fn reduce_bit_depth_8_or_less(png: &PngImage, mut minimum_bits: usize) -> Option<PngImage> {
    assert!((1..8).contains(&minimum_bits));
    let mut reduced = BitVec::with_capacity(png.data.len() * 8);
    let bit_depth: usize = png.ihdr.bit_depth.as_u8() as usize;
    if minimum_bits >= bit_depth {
        return None;
    }
    for line in png.scan_lines() {
        if png.ihdr.color_type == ColorType::Indexed {
            let line_max = line
                .data
                .iter()
                .map(|&byte| match png.ihdr.bit_depth {
                    BitDepth::Two => (byte & 0x3)
                        .max((byte >> 2) & 0x3)
                        .max((byte >> 4) & 0x3)
                        .max(byte >> 6),
                    BitDepth::Four => (byte & 0xF).max(byte >> 4),
                    _ => byte,
                })
                .max()
                .unwrap_or(0);
            let required_bits = match line_max {
                x if x > 0x0F => 8,
                x if x > 0x03 => 4,
                x if x > 0x01 => 2,
                _ => 1,
            };
            if required_bits > minimum_bits {
                minimum_bits = required_bits;
                if minimum_bits >= bit_depth {
                    // Not reducable
                    return None;
                }
            }
        } else {
            let bit_vec = BitVec::from_bytes(&line.data);
            for byte in bit_vec.to_bytes() {
                while minimum_bits < bit_depth {
                    let permutations: &[u8] = if minimum_bits == 1 {
                        &ONE_BIT_PERMUTATIONS
                    } else if minimum_bits == 2 {
                        &TWO_BIT_PERMUTATIONS
                    } else if minimum_bits == 4 {
                        &FOUR_BIT_PERMUTATIONS
                    } else {
                        return None;
                    };
                    if permutations.iter().any(|perm| *perm == byte) {
                        break;
                    } else {
                        minimum_bits <<= 1;
                    }
                }
            }
        }
    }

    for line in png.scan_lines() {
        reduced.extend(BitVec::from_bytes(&[line.filter]));
        let bit_vec = BitVec::from_bytes(&line.data);
        for (i, bit) in bit_vec.iter().enumerate() {
            let bit_index = bit_depth - (i % bit_depth);
            if bit_index <= minimum_bits {
                reduced.push(bit);
            }
        }
        // Pad end of line to get 8 bits per byte
        while reduced.len() % 8 != 0 {
            reduced.push(false);
        }
    }

    Some(PngImage {
        data: reduced.to_bytes(),
        ihdr: IhdrData {
            bit_depth: BitDepth::from_u8(minimum_bits as u8),
            ..png.ihdr
        },
        aux_headers: png.aux_headers.clone(),
        palette: png.palette.clone(),
        transparency_pixel: png.transparency_pixel.clone(),
    })
}
<|endoftext|>


<commit_before>fn main(){
  println!{"{:?}", algoritmo_ordenacao::insertion_sort::insertion_sort(vec![54,42,11,33,24,99,77,80])};
}
fn insertion_sort(mut vetor: Vec<i32>) -> Vec<i32> {
  for i in 1..vetor.len() {
    let mut index: i32 = i as i32;
    while index > 0 && vetor[index as usize] < vetor[index as usize - 1] {
      vetor.swap(index as usize, index as usize - 1);
      index -= 1;
    }
  }
  vetor
}
<commit_msg>ajustes<commit_after>fn main(){
  println!{"{:?}", insertion_sort(vec![54,42,11,33,24,99,77,80])};
}
fn insertion_sort(mut vetor: Vec<i32>) -> Vec<i32> {
  for i in 1..vetor.len() {
    let mut index: i32 = i as i32;
    while index > 0 && vetor[index as usize] < vetor[index as usize - 1] {
      vetor.swap(index as usize, index as usize - 1);
      index -= 1;
    }
  }
  vetor
}
<|endoftext|>


<commit_before>use super::{Polynom, Polynom64};

pub trait RollingHash64 {
    fn reset(&mut self);
    fn reset_and_prefill_window<I>(&mut self, &mut I) -> usize where I: Iterator<Item=u8>;
    fn slide(&mut self, &u8);
    fn get_hash(&self) -> &Polynom64;
}

pub struct Rabin64 {
    // Configuration
    window_size: usize, // The size of the data window used in the hash calculation.
    window_size_mask: usize, // = window_size - 1, supposing that it is an exponent of 2.

    // Precalculations
    polynom_shift: i32,
    out_table: [Polynom64; 256],
    mod_table: [Polynom64; 256],

    // Current state
    window_data: Vec<u8>,
    window_index: usize,
    pub hash: Polynom64,
}

// Default irreductible modulo polynom.
pub const MOD_POLYNOM: Polynom64 = 0x3DA3358B4DC173;

impl Rabin64 {
    pub fn calculate_out_table(window_size: usize, mod_polynom: &Polynom64) -> [Polynom64; 256] {
        let mut out_table = [0; 256];
        for b in 0..256 {
            let mut hash = (b as Polynom64).modulo(mod_polynom);
            for _ in 0..window_size - 1 {
                hash <<= 8;
                hash = hash.modulo(mod_polynom);
            }
            out_table[b] = hash;
        }

        out_table
    }

    pub fn calculate_mod_table(mod_polynom: &Polynom64) -> [Polynom64; 256] {
        let mut mod_table = [0; 256];
        let k = mod_polynom.degree();
        for b in 0..256 {
            let p: Polynom64 = (b as Polynom64) << k;
            mod_table[b] = p.modulo(mod_polynom) | p;
        }

        mod_table
    }

    pub fn new(window_size_nb_bits: u32) -> Rabin64 {
    	Self::new_with_polynom(window_size_nb_bits, &MOD_POLYNOM)
    }

    pub fn new_with_polynom(window_size_nb_bits: u32, mod_polynom: &Polynom64) -> Rabin64 {
    	let window_size = 1 << window_size_nb_bits;

        let mut window_data = Vec::with_capacity(window_size);
        window_data.resize(window_size, 0);

        Rabin64 {
            window_size: window_size,
            window_size_mask: window_size - 1,
            polynom_shift: mod_polynom.degree() - 8,
            out_table: Self::calculate_out_table(window_size, mod_polynom),
            mod_table: Self::calculate_mod_table(mod_polynom),
            window_data: window_data,
            window_index: 0,
            hash: 0,
        }
    }

    #[cfg(test)]
    pub fn hash_block(&mut self, bytes: &[u8], mod_polynom: &Polynom64) {
        for v in bytes {
            self.hash <<= 8;
            self.hash |= *v as Polynom64;
            self.hash = self.hash.modulo(&mod_polynom);
        }
    }

}

impl RollingHash64 for Rabin64 {

    fn reset(&mut self) {
        self.window_data.clear();
        self.window_data.resize(self.window_size, 0);
        self.window_index = 0;
        self.hash = 0;

        // Not needed.
        // self.slide(1);
    }

    // Attempt to fills the window - 1 byte.
    fn reset_and_prefill_window<I>(&mut self, iter: &mut I) -> usize where I: Iterator<Item=u8> {
        self.hash = 0;
        let mut nb_bytes_read = 0;
        for _ in 0..self.window_size-1 {
            match iter.next() {
                Some(b) => {
                    // Take the old value out of the window and the hash.
                    // ... let's suppose that the buffer contains zeroes, do nothing.

                    // Put the new value in the window and in the hash.
                    self.window_data[self.window_index] = b;
                    let mod_index = (self.hash >> self.polynom_shift) & 255;
                    self.hash <<= 8;
                    self.hash |= b as Polynom64;
                    self.hash ^= self.mod_table[mod_index as usize];

                    // Move the windowIndex to the next position.
                    self.window_index = (self.window_index + 1) & self.window_size_mask;

                    nb_bytes_read += 1;
                },
                None => break,
            }
        }

        // Because we didn't overwrite that element in the loop above.
        self.window_data[self.window_index] = 0;

        nb_bytes_read
    }

    #[inline]
    fn slide(&mut self, byte: &u8) {
        // Take the old value out of the window and the hash.
        let out_value = self.window_data[self.window_index];
        self.hash ^= self.out_table[out_value as usize];

        // Put the new value in the window and in the hash.
        self.window_data[self.window_index] = *byte;
        let mod_index = (self.hash >> self.polynom_shift) & 255;
        self.hash <<= 8;
        self.hash |= *byte as Polynom64;
        self.hash ^= self.mod_table[mod_index as usize];

        // Move the windowIndex to the next position.
        self.window_index = (self.window_index + 1) & self.window_size_mask;
    }

    #[inline]
    fn get_hash(&self) -> &Polynom64 {
        &self.hash
    }
}

#[cfg(test)]
mod tests {
    use super::super::polynom::Polynom64;
    use super::*;

    fn to_hex_string(polynoms: &[Polynom64], prefix: &str) -> String {
        let strs: Vec<String> = polynoms.iter()
            .map(|p| format!("{}{:016x} {}", prefix, p, 0))
            .collect();
        strs.join("\n")
    }

    #[test]
    fn print_tables() {
        let out_table = Rabin64::calculate_out_table(32, &MOD_POLYNOM);
        let mod_table = Rabin64::calculate_mod_table(&MOD_POLYNOM);
        println!("{}", to_hex_string(&out_table[..], "outTable "));
        println!("{}", to_hex_string(&mod_table[..], "modTable "));
    }

   #[test]
   fn rabin_hash() {
       use std::cmp::max;

       // Random meaningless data.
       let data = [17u8, 28, 53, 64, 175, 216, 27, 208, 109, 130, 143, 35, 93, 244, 45, 18, 64,
                   193, 204, 59, 169, 139, 53, 59, 55, 65, 242, 73, 60, 198, 45, 22, 56, 90, 81,
                   181];

       let mut rabin1 = Rabin64::new(5);
       let mut rabin2 = Rabin64::new(5);

       // Block by block, no optimization, used raw modulo formula.
       for i in 0..data.len() {
           let block = &data[max(31, i) - 31..i + 1];
           rabin1.reset();
           rabin1.hash_block(block, &MOD_POLYNOM);

           rabin2.slide(&data[i]);

           //println!("{:02} {:02} {:016x} {:016x} {:?}", i, block.len(), rabin1.hash, rabin2.hash, block);
           assert_eq!(rabin1.hash, rabin2.hash);
       }
   }

}
<commit_msg>Brings back the `prefill_window()` function, for reference.<commit_after>use super::{Polynom, Polynom64};

pub trait RollingHash64 {
    fn reset(&mut self);
    fn prefill_window<I>(&mut self, &mut I) -> usize where I: Iterator<Item=u8>;
    fn reset_and_prefill_window<I>(&mut self, &mut I) -> usize where I: Iterator<Item=u8>;
    fn slide(&mut self, &u8);
    fn get_hash(&self) -> &Polynom64;
}

pub struct Rabin64 {
    // Configuration
    window_size: usize, // The size of the data window used in the hash calculation.
    window_size_mask: usize, // = window_size - 1, supposing that it is an exponent of 2.

    // Precalculations
    polynom_shift: i32,
    out_table: [Polynom64; 256],
    mod_table: [Polynom64; 256],

    // Current state
    window_data: Vec<u8>,
    window_index: usize,
    pub hash: Polynom64,
}

// Default irreductible modulo polynom.
pub const MOD_POLYNOM: Polynom64 = 0x3DA3358B4DC173;

impl Rabin64 {
    pub fn calculate_out_table(window_size: usize, mod_polynom: &Polynom64) -> [Polynom64; 256] {
        let mut out_table = [0; 256];
        for b in 0..256 {
            let mut hash = (b as Polynom64).modulo(mod_polynom);
            for _ in 0..window_size - 1 {
                hash <<= 8;
                hash = hash.modulo(mod_polynom);
            }
            out_table[b] = hash;
        }

        out_table
    }

    pub fn calculate_mod_table(mod_polynom: &Polynom64) -> [Polynom64; 256] {
        let mut mod_table = [0; 256];
        let k = mod_polynom.degree();
        for b in 0..256 {
            let p: Polynom64 = (b as Polynom64) << k;
            mod_table[b] = p.modulo(mod_polynom) | p;
        }

        mod_table
    }

    pub fn new(window_size_nb_bits: u32) -> Rabin64 {
    	Self::new_with_polynom(window_size_nb_bits, &MOD_POLYNOM)
    }

    pub fn new_with_polynom(window_size_nb_bits: u32, mod_polynom: &Polynom64) -> Rabin64 {
    	let window_size = 1 << window_size_nb_bits;

        let mut window_data = Vec::with_capacity(window_size);
        window_data.resize(window_size, 0);

        Rabin64 {
            window_size: window_size,
            window_size_mask: window_size - 1,
            polynom_shift: mod_polynom.degree() - 8,
            out_table: Self::calculate_out_table(window_size, mod_polynom),
            mod_table: Self::calculate_mod_table(mod_polynom),
            window_data: window_data,
            window_index: 0,
            hash: 0,
        }
    }

    #[cfg(test)]
    pub fn hash_block(&mut self, bytes: &[u8], mod_polynom: &Polynom64) {
        for v in bytes {
            self.hash <<= 8;
            self.hash |= *v as Polynom64;
            self.hash = self.hash.modulo(&mod_polynom);
        }
    }

}

impl RollingHash64 for Rabin64 {

    fn reset(&mut self) {
        self.window_data.clear();
        self.window_data.resize(self.window_size, 0);
        self.window_index = 0;
        self.hash = 0;

        // Not needed.
        // self.slide(1);
    }

    // Attempt to fills the window - 1 byte.
    fn prefill_window<I>(&mut self, iter: &mut I) -> usize where I: Iterator<Item=u8> {
        let mut nb_bytes_read = 0;
        for _ in 0..self.window_size-1 {
            match iter.next() {
                Some(b) => {
                    self.slide(&b);
                    nb_bytes_read += 1;
                },
                None => break,
            }
        }

        nb_bytes_read
    }

    // Combines a reset with a prefill in an optimized way.
    fn reset_and_prefill_window<I>(&mut self, iter: &mut I) -> usize where I: Iterator<Item=u8> {
        self.hash = 0;
        let mut nb_bytes_read = 0;
        for _ in 0..self.window_size-1 {
            match iter.next() {
                Some(b) => {
                    // Take the old value out of the window and the hash.
                    // ... let's suppose that the buffer contains zeroes, do nothing.

                    // Put the new value in the window and in the hash.
                    self.window_data[self.window_index] = b;
                    let mod_index = (self.hash >> self.polynom_shift) & 255;
                    self.hash <<= 8;
                    self.hash |= b as Polynom64;
                    self.hash ^= self.mod_table[mod_index as usize];

                    // Move the windowIndex to the next position.
                    self.window_index = (self.window_index + 1) & self.window_size_mask;

                    nb_bytes_read += 1;
                },
                None => break,
            }
        }

        // Because we didn't overwrite that element in the loop above.
        self.window_data[self.window_index] = 0;

        nb_bytes_read
    }

    #[inline]
    fn slide(&mut self, byte: &u8) {
        // Take the old value out of the window and the hash.
        let out_value = self.window_data[self.window_index];
        self.hash ^= self.out_table[out_value as usize];

        // Put the new value in the window and in the hash.
        self.window_data[self.window_index] = *byte;
        let mod_index = (self.hash >> self.polynom_shift) & 255;
        self.hash <<= 8;
        self.hash |= *byte as Polynom64;
        self.hash ^= self.mod_table[mod_index as usize];

        // Move the windowIndex to the next position.
        self.window_index = (self.window_index + 1) & self.window_size_mask;
    }

    #[inline]
    fn get_hash(&self) -> &Polynom64 {
        &self.hash
    }
}

#[cfg(test)]
mod tests {
    use super::super::polynom::Polynom64;
    use super::*;

    fn to_hex_string(polynoms: &[Polynom64], prefix: &str) -> String {
        let strs: Vec<String> = polynoms.iter()
            .map(|p| format!("{}{:016x} {}", prefix, p, 0))
            .collect();
        strs.join("\n")
    }

    #[test]
    fn print_tables() {
        let out_table = Rabin64::calculate_out_table(32, &MOD_POLYNOM);
        let mod_table = Rabin64::calculate_mod_table(&MOD_POLYNOM);
        println!("{}", to_hex_string(&out_table[..], "outTable "));
        println!("{}", to_hex_string(&mod_table[..], "modTable "));
    }

   #[test]
   fn rabin_hash() {
       use std::cmp::max;

       // Random meaningless data.
       let data = [17u8, 28, 53, 64, 175, 216, 27, 208, 109, 130, 143, 35, 93, 244, 45, 18, 64,
                   193, 204, 59, 169, 139, 53, 59, 55, 65, 242, 73, 60, 198, 45, 22, 56, 90, 81,
                   181];

       let mut rabin1 = Rabin64::new(5);
       let mut rabin2 = Rabin64::new(5);

       // Block by block, no optimization, used raw modulo formula.
       for i in 0..data.len() {
           let block = &data[max(31, i) - 31..i + 1];
           rabin1.reset();
           rabin1.hash_block(block, &MOD_POLYNOM);

           rabin2.slide(&data[i]);

           //println!("{:02} {:02} {:016x} {:016x} {:?}", i, block.len(), rabin1.hash, rabin2.hash, block);
           assert_eq!(rabin1.hash, rabin2.hash);
       }
   }

}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! The service topologies.
//!
//! A service topology is a [state machine](../state_machine) that wraps the lifecycle events of a service around the
//! process supervisor and package manager. It is responsible for:
//!
//! 1. Processing the main event loop
//! 1. Registering callbacks with the [discovery](../discovery) system
//!
//! Typically, topologies are created from the [start](../command/start) command.

pub mod standalone;
pub mod leader;
pub mod initializer;

use std::mem;
use std::net::SocketAddrV4;
use std::ops::DerefMut;
use std::str::FromStr;
use std::sync::{Arc, RwLock};
use std::sync::mpsc::TryRecvError;
use std::thread;
use std::time::Duration;

use wonder;

use state_machine::StateMachine;
use census::{self, CensusList};
use common::gossip_file::GossipFileList;
use package::{self, Package, PackageUpdaterActor};
use util::signals::SignalNotifier;
use error::{Result, SupError};
use config::Config;
use service_config::ServiceConfig;
use sidecar;
use supervisor::Supervisor;
use gossip;
use gossip::rumor::{Rumor, RumorList};
use gossip::member::MemberList;
use election::ElectionList;
use time::SteadyTime;
use util::signals;
use config::UpdateStrategy;

static LOGKEY: &'static str = "TP";
static MINIMUM_LOOP_TIME_MS: i64 = 200;

#[derive(PartialEq, Eq, Debug, RustcEncodable)]
pub enum Topology {
    Standalone,
    Leader,
    Initializer,
}

impl Default for Topology {
    fn default() -> Topology {
        Topology::Standalone
    }
}

/// Viable states for the topologies. Not every topology will implement every state.
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
pub enum State {
    Init,
    MinimumQuorum,
    WaitingForQuorum,
    RestoreDataset,
    DetermineViability,
    BecomeLeader,
    BecomeFollower,
    CheckForElection,
    Election,
    StartElection,
    InElection,
    Leader,
    Follower,
    Configure,
    Initializing,
    Starting,
    Running,
}

/// The topology `Worker` is where everything our state machine needs between states lives.
pub struct Worker<'a> {
    /// The package we are supervising
    pub package: Arc<RwLock<Package>>,
    /// Name of the package being supervised
    pub package_name: String,
    /// A pointer to our current Config
    pub config: &'a Config,
    /// The topology we are running
    pub topology: String,
    /// Our Service Configuration; manages changes to our configuration,
    pub service_config: Arc<RwLock<ServiceConfig>>,
    /// The Gossip Server; listens for inbound gossip traffic
    pub gossip_server: gossip::server::Server,
    pub census_list: Arc<RwLock<CensusList>>,
    pub rumor_list: Arc<RwLock<RumorList>>,
    pub election_list: Arc<RwLock<ElectionList>>,
    pub member_list: Arc<RwLock<MemberList>>,
    pub gossip_file_list: Arc<RwLock<GossipFileList>>,
    /// Our Sidecar Actor; exposes a restful HTTP interface to the outside world
    pub sidecar_actor: sidecar::SidecarActor,
    /// Watches a package Depot for updates and signals the main thread when an update is available. Optionally
    /// started if a value is passed for the url option on startup.
    pub pkg_updater: Option<PackageUpdaterActor>,
    /// The service supervisor
    pub supervisor: Arc<RwLock<Supervisor>>,
    pub return_state: Option<State>,
}

impl<'a> Worker<'a> {
    /// Create a new worker
    ///
    /// Automatically sets the backend to Etcd.
    pub fn new(package: Package, topology: String, config: &'a Config) -> Result<Worker<'a>> {
        let mut pkg_updater = None;
        let package_name = package.name.clone();
        let package_exposes = package.exposes().clone();
        let package_port = package_exposes.first().map(|e| e.clone());
        let package_ident = package.ident().clone();
        let pkg_lock = Arc::new(RwLock::new(package));
        let pkg_lock_1 = pkg_lock.clone();

        match config.update_strategy() {
            UpdateStrategy::None => {},
            _ => {
                let pkg_lock_2 = pkg_lock.clone();
                if let &Some(ref url) = config.url() {
                    pkg_updater = Some(package::PackageUpdater::start(url, pkg_lock_2));
                }
            }
        }

        let gossip_server = gossip::server::Server::new(String::from(config.gossip_listen_ip()),
                                                        config.gossip_listen_port(),
                                                        config.gossip_permanent(),
                                                        config.ring().clone(),
                                                        package_name.clone(),
                                                        config.group().to_string(),
                                                        config.organization().clone(),
                                                        Some(package_exposes),
                                                        package_port);

        try!(gossip_server.start_inbound());
        try!(gossip_server.initial_peers(config.gossip_peer()));
        gossip_server.start_outbound();
        gossip_server.start_failure_detector();
        census::start_health_adjuster(gossip_server.census_list.clone(),
                                      gossip_server.member_list.clone());

        // Setup the Service Configuration
        let service_config = {
            let cl = gossip_server.census_list.read().unwrap();
            let pkg = pkg_lock.read().unwrap();
            let sc = try!(ServiceConfig::new(&config, &pkg, &cl, config.bind()));
            sc
        };
        let service_config_lock = Arc::new(RwLock::new(service_config));
        let service_config_lock_1 = service_config_lock.clone();

        let supervisor = Arc::new(RwLock::new(Supervisor::new(package_ident)));

        let sidecar_ml = gossip_server.member_list.clone();
        let sidecar_rl = gossip_server.rumor_list.clone();
        let sidecar_cl = gossip_server.census_list.clone();
        let sidecar_gfl = gossip_server.gossip_file_list.clone();
        let sidecar_detector = gossip_server.detector.clone();
        let sidecar_el = gossip_server.election_list.clone();
        let sidecar_sup = supervisor.clone();
        let sidecar_listen = try!(SocketAddrV4::from_str(&format!("{}:{}",
                                                                  &config.http_listen_ip(),
                                                                  config.http_listen_port())));
        Ok(Worker {
            package: pkg_lock,
            package_name: package_name,
            topology: topology,
            config: config,
            census_list: gossip_server.census_list.clone(),
            rumor_list: gossip_server.rumor_list.clone(),
            election_list: gossip_server.election_list.clone(),
            gossip_file_list: gossip_server.gossip_file_list.clone(),
            member_list: gossip_server.member_list.clone(),
            gossip_server: gossip_server,
            service_config: service_config_lock,
            sidecar_actor: sidecar::Sidecar::start(sidecar_listen,
                                                   pkg_lock_1,
                                                   service_config_lock_1,
                                                   sidecar_ml,
                                                   sidecar_rl,
                                                   sidecar_cl,
                                                   sidecar_detector,
                                                   sidecar_el,
                                                   sidecar_sup,
                                                   sidecar_gfl),
            supervisor: supervisor,
            pkg_updater: pkg_updater,
            return_state: None,
        })
    }

    /// update a package, but does NOT restart the service
    pub fn update_package(&self, updated: Package) -> Result<()> {
        let service_config = self.service_config.read().unwrap();
        {
            let mut package = self.package.write().unwrap();
            mem::replace(package.deref_mut(), updated);
        }
        let package = self.package.read().unwrap();
        try!(package.copy_run(&service_config));
        Ok(())
    }
}

/// The main loop of a topology.
///
/// 1. Loops forever
/// 1. Checks if we have caught a signal; if so, acts on the signal. (May exit entirely)
/// 1. Checks the current `state` of our [StateMachine](../state_machine)
/// 1. If it is running, we run a non-blocking `waitpid`, and inspect why the child died;
///    depending on the circumstances, we may exit with an error here
/// 1. Process any discovery events
/// 1. Trigger the next iteration of the state machine
///
/// # Failures
///
/// * We fail to send a signal to the supervisor
/// * We fail to join the supervisor thread
/// * The supervisor dies unexpectedly
/// * The discovery subsystem returns an error
/// * The topology state machine returns an error
fn run_internal<'a>(sm: &mut StateMachine<State, Worker<'a>, SupError>,
                    worker: &mut Worker<'a>)
                    -> Result<()> {
    {
        let package = worker.package.read().unwrap();
        let service_config = worker.service_config.read().unwrap();
        try!(package.create_svc_path());
        try!(package.copy_run(&service_config));
    }
    let handler = wonder::actor::Builder::new(SignalNotifier)
        .name("signal-handler".to_string())
        .start(())
        .unwrap();
    loop {
        let start_time = SteadyTime::now();
        match handler.receiver.try_recv() {
            Ok(wonder::actor::Message::Cast(signals::Message::Signal(sig))) => {
                debug!("SIG = {:?}", sig);
                match sig {
                    signals::Signal::SIGINT | signals::Signal::SIGTERM => {
                        let mut supervisor = worker.supervisor.write().unwrap();
                        try!(supervisor.down());
                        break;
                    }
                    _ => {
                        outputln!("Forwarding {:?} on to the supervised process", sig);
                        let supervisor = worker.supervisor.write().unwrap();
                        try!(supervisor.send_unix_signal(sig.clone()));
                    }
                };
            }
            Ok(_) => {}
            Err(TryRecvError::Empty) => {}
            Err(TryRecvError::Disconnected) => {
                panic!("signal handler crashed!");
            }
        }

        {
            let mut supervisor = worker.supervisor.write().unwrap();
            try!(supervisor.check_process());
        }

        let mut restart_process = false;

        // This section, and the following really need to be refactored:
        //
        // 1. We check to see if we are in an event a bunch of times
        // 2. We potentially restart 3 different times - twice for reconfigure, and once for
        //    file_udpated. That's pretty yucky.
        //
        // Love, Adam
        {
            // Manage the census
            let (write_census, in_event, write_rumor, me_clone) = {
                let cl = worker.census_list.read().unwrap();
                let census = cl.local_census();
                (cl.needs_write(), census.in_event, census.me().needs_write(), census.me().clone())
            };

            if write_census {
                if !in_event {
                    let mut service_config = worker.service_config.write().unwrap();
                    let cl = worker.census_list.read().unwrap();
                    service_config.svc(&cl);
                    service_config.bind(worker.config.bind(), &cl);
                }
                if write_rumor {
                    outputln!("Writing our census rumor: {:#?}", me_clone);
                    let mut rl = worker.rumor_list.write().unwrap();
                    rl.add_rumor(Rumor::census_entry(me_clone));
                }
                let mut cl = worker.census_list.write().unwrap();
                cl.written();
            }

            // Don't bother trying to reconfigure if we are in an event - just wait till
            // everything settles down.
            {
                let census_list = worker.census_list.read().unwrap();
                let census = census_list.local_census();
                if !census.in_event {
                    let mut service_config = worker.service_config.write().unwrap();
                    if service_config.needs_write {
                        let package = worker.package.read().unwrap();
                        // Write the configuration, and restart if needed
                        if try!(service_config.write(&package)) {
                            try!(package.copy_run(&service_config));
                            try!(package.reconfigure(&service_config));
                            outputln!("Restarting because the service config was updated via the \
                                       census");
                            restart_process = true;
                        }
                    }
                }
            }
        }

        {
            let in_event = {
                let census_list = worker.census_list.read().unwrap();
                let census = census_list.local_census();
                census.in_event
            };
            let (needs_file_updated, needs_reconfigure) = if in_event {
                (false, false)
            } else {
                let mut gossip_file_list = worker.gossip_file_list.write().unwrap();
                let needs_write = {
                    gossip_file_list.needs_write()
                };
                if needs_write {
                    try!(gossip_file_list.write())
                } else {
                    (false, false)
                }
            };
            if needs_file_updated {
                let service_config = worker.service_config.read().unwrap();
                let package = worker.package.read().unwrap();
                let existed = try!(package.file_updated(&service_config));
                if !existed {
                    restart_process = true;
                }
            }
            if needs_reconfigure {
                let mut service_config = worker.service_config.write().unwrap();
                let package = worker.package.read().unwrap();
                service_config.cfg(&package);
                if try!(service_config.write(&package)) {
                    try!(package.copy_run(&service_config));
                    let existed = try!(package.reconfigure(&service_config));
                    if !existed {
                        restart_process = true;
                    }
                }
            }
        }

        if let Some(ref updater) = worker.pkg_updater {
            match updater.receiver.try_recv() {
                Ok(wonder::actor::Message::Cast(package::UpdaterMessage::Update(package))) => {
                    debug!("Main loop received package update notification: {:?}",
                           &package);
                    try!(worker.update_package(package));
                    try!(package::PackageUpdater::run(&updater));
                    // force the package to restart
                    outputln!("Restarting because the package was updated");
                    restart_process = true;
                }
                Ok(_) => {}
                Err(TryRecvError::Empty) => {}
                Err(TryRecvError::Disconnected) => {
                    panic!("package updater crashed!");
                }
            }
        }

        {
            let mut supervisor = worker.supervisor.write().unwrap();
            // If our target is that the process is up
            if supervisor.is_up() {
                // And no process is running
                if supervisor.pid.is_none() {
                    // Start a new one
                    try!(supervisor.start());
                } else {
                    // If we were supposed to restart
                    if restart_process {
                        // And we have ever started before...
                        if supervisor.has_started {
                            // Restart
                            try!(supervisor.restart());
                        }
                    }
                }
            }
        }

        // Next state!
        try!(sm.next(worker));

        // Slow down our loop
        let elapsed_time = SteadyTime::now() - start_time;
        let elapsed_millis = elapsed_time.num_milliseconds();

        if elapsed_millis < MINIMUM_LOOP_TIME_MS {
            thread::sleep(Duration::from_millis((MINIMUM_LOOP_TIME_MS - elapsed_millis) as u64));
        }
    }
    Ok(())
}
<commit_msg>Remove chattiness on issuing new census rumors Signed-off-by: Julian C. Dunn <jdunn@chef.io><commit_after>// Copyright (c) 2016 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! The service topologies.
//!
//! A service topology is a [state machine](../state_machine) that wraps the lifecycle events of a service around the
//! process supervisor and package manager. It is responsible for:
//!
//! 1. Processing the main event loop
//! 1. Registering callbacks with the [discovery](../discovery) system
//!
//! Typically, topologies are created from the [start](../command/start) command.

pub mod standalone;
pub mod leader;
pub mod initializer;

use std::mem;
use std::net::SocketAddrV4;
use std::ops::DerefMut;
use std::str::FromStr;
use std::sync::{Arc, RwLock};
use std::sync::mpsc::TryRecvError;
use std::thread;
use std::time::Duration;

use wonder;

use state_machine::StateMachine;
use census::{self, CensusList};
use common::gossip_file::GossipFileList;
use package::{self, Package, PackageUpdaterActor};
use util::signals::SignalNotifier;
use error::{Result, SupError};
use config::Config;
use service_config::ServiceConfig;
use sidecar;
use supervisor::Supervisor;
use gossip;
use gossip::rumor::{Rumor, RumorList};
use gossip::member::MemberList;
use election::ElectionList;
use time::SteadyTime;
use util::signals;
use config::UpdateStrategy;

static LOGKEY: &'static str = "TP";
static MINIMUM_LOOP_TIME_MS: i64 = 200;

#[derive(PartialEq, Eq, Debug, RustcEncodable)]
pub enum Topology {
    Standalone,
    Leader,
    Initializer,
}

impl Default for Topology {
    fn default() -> Topology {
        Topology::Standalone
    }
}

/// Viable states for the topologies. Not every topology will implement every state.
#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
pub enum State {
    Init,
    MinimumQuorum,
    WaitingForQuorum,
    RestoreDataset,
    DetermineViability,
    BecomeLeader,
    BecomeFollower,
    CheckForElection,
    Election,
    StartElection,
    InElection,
    Leader,
    Follower,
    Configure,
    Initializing,
    Starting,
    Running,
}

/// The topology `Worker` is where everything our state machine needs between states lives.
pub struct Worker<'a> {
    /// The package we are supervising
    pub package: Arc<RwLock<Package>>,
    /// Name of the package being supervised
    pub package_name: String,
    /// A pointer to our current Config
    pub config: &'a Config,
    /// The topology we are running
    pub topology: String,
    /// Our Service Configuration; manages changes to our configuration,
    pub service_config: Arc<RwLock<ServiceConfig>>,
    /// The Gossip Server; listens for inbound gossip traffic
    pub gossip_server: gossip::server::Server,
    pub census_list: Arc<RwLock<CensusList>>,
    pub rumor_list: Arc<RwLock<RumorList>>,
    pub election_list: Arc<RwLock<ElectionList>>,
    pub member_list: Arc<RwLock<MemberList>>,
    pub gossip_file_list: Arc<RwLock<GossipFileList>>,
    /// Our Sidecar Actor; exposes a restful HTTP interface to the outside world
    pub sidecar_actor: sidecar::SidecarActor,
    /// Watches a package Depot for updates and signals the main thread when an update is available. Optionally
    /// started if a value is passed for the url option on startup.
    pub pkg_updater: Option<PackageUpdaterActor>,
    /// The service supervisor
    pub supervisor: Arc<RwLock<Supervisor>>,
    pub return_state: Option<State>,
}

impl<'a> Worker<'a> {
    /// Create a new worker
    ///
    /// Automatically sets the backend to Etcd.
    pub fn new(package: Package, topology: String, config: &'a Config) -> Result<Worker<'a>> {
        let mut pkg_updater = None;
        let package_name = package.name.clone();
        let package_exposes = package.exposes().clone();
        let package_port = package_exposes.first().map(|e| e.clone());
        let package_ident = package.ident().clone();
        let pkg_lock = Arc::new(RwLock::new(package));
        let pkg_lock_1 = pkg_lock.clone();

        match config.update_strategy() {
            UpdateStrategy::None => {},
            _ => {
                let pkg_lock_2 = pkg_lock.clone();
                if let &Some(ref url) = config.url() {
                    pkg_updater = Some(package::PackageUpdater::start(url, pkg_lock_2));
                }
            }
        }

        let gossip_server = gossip::server::Server::new(String::from(config.gossip_listen_ip()),
                                                        config.gossip_listen_port(),
                                                        config.gossip_permanent(),
                                                        config.ring().clone(),
                                                        package_name.clone(),
                                                        config.group().to_string(),
                                                        config.organization().clone(),
                                                        Some(package_exposes),
                                                        package_port);

        try!(gossip_server.start_inbound());
        try!(gossip_server.initial_peers(config.gossip_peer()));
        gossip_server.start_outbound();
        gossip_server.start_failure_detector();
        census::start_health_adjuster(gossip_server.census_list.clone(),
                                      gossip_server.member_list.clone());

        // Setup the Service Configuration
        let service_config = {
            let cl = gossip_server.census_list.read().unwrap();
            let pkg = pkg_lock.read().unwrap();
            let sc = try!(ServiceConfig::new(&config, &pkg, &cl, config.bind()));
            sc
        };
        let service_config_lock = Arc::new(RwLock::new(service_config));
        let service_config_lock_1 = service_config_lock.clone();

        let supervisor = Arc::new(RwLock::new(Supervisor::new(package_ident)));

        let sidecar_ml = gossip_server.member_list.clone();
        let sidecar_rl = gossip_server.rumor_list.clone();
        let sidecar_cl = gossip_server.census_list.clone();
        let sidecar_gfl = gossip_server.gossip_file_list.clone();
        let sidecar_detector = gossip_server.detector.clone();
        let sidecar_el = gossip_server.election_list.clone();
        let sidecar_sup = supervisor.clone();
        let sidecar_listen = try!(SocketAddrV4::from_str(&format!("{}:{}",
                                                                  &config.http_listen_ip(),
                                                                  config.http_listen_port())));
        Ok(Worker {
            package: pkg_lock,
            package_name: package_name,
            topology: topology,
            config: config,
            census_list: gossip_server.census_list.clone(),
            rumor_list: gossip_server.rumor_list.clone(),
            election_list: gossip_server.election_list.clone(),
            gossip_file_list: gossip_server.gossip_file_list.clone(),
            member_list: gossip_server.member_list.clone(),
            gossip_server: gossip_server,
            service_config: service_config_lock,
            sidecar_actor: sidecar::Sidecar::start(sidecar_listen,
                                                   pkg_lock_1,
                                                   service_config_lock_1,
                                                   sidecar_ml,
                                                   sidecar_rl,
                                                   sidecar_cl,
                                                   sidecar_detector,
                                                   sidecar_el,
                                                   sidecar_sup,
                                                   sidecar_gfl),
            supervisor: supervisor,
            pkg_updater: pkg_updater,
            return_state: None,
        })
    }

    /// update a package, but does NOT restart the service
    pub fn update_package(&self, updated: Package) -> Result<()> {
        let service_config = self.service_config.read().unwrap();
        {
            let mut package = self.package.write().unwrap();
            mem::replace(package.deref_mut(), updated);
        }
        let package = self.package.read().unwrap();
        try!(package.copy_run(&service_config));
        Ok(())
    }
}

/// The main loop of a topology.
///
/// 1. Loops forever
/// 1. Checks if we have caught a signal; if so, acts on the signal. (May exit entirely)
/// 1. Checks the current `state` of our [StateMachine](../state_machine)
/// 1. If it is running, we run a non-blocking `waitpid`, and inspect why the child died;
///    depending on the circumstances, we may exit with an error here
/// 1. Process any discovery events
/// 1. Trigger the next iteration of the state machine
///
/// # Failures
///
/// * We fail to send a signal to the supervisor
/// * We fail to join the supervisor thread
/// * The supervisor dies unexpectedly
/// * The discovery subsystem returns an error
/// * The topology state machine returns an error
fn run_internal<'a>(sm: &mut StateMachine<State, Worker<'a>, SupError>,
                    worker: &mut Worker<'a>)
                    -> Result<()> {
    {
        let package = worker.package.read().unwrap();
        let service_config = worker.service_config.read().unwrap();
        try!(package.create_svc_path());
        try!(package.copy_run(&service_config));
    }
    let handler = wonder::actor::Builder::new(SignalNotifier)
        .name("signal-handler".to_string())
        .start(())
        .unwrap();
    loop {
        let start_time = SteadyTime::now();
        match handler.receiver.try_recv() {
            Ok(wonder::actor::Message::Cast(signals::Message::Signal(sig))) => {
                debug!("SIG = {:?}", sig);
                match sig {
                    signals::Signal::SIGINT | signals::Signal::SIGTERM => {
                        let mut supervisor = worker.supervisor.write().unwrap();
                        try!(supervisor.down());
                        break;
                    }
                    _ => {
                        outputln!("Forwarding {:?} on to the supervised process", sig);
                        let supervisor = worker.supervisor.write().unwrap();
                        try!(supervisor.send_unix_signal(sig.clone()));
                    }
                };
            }
            Ok(_) => {}
            Err(TryRecvError::Empty) => {}
            Err(TryRecvError::Disconnected) => {
                panic!("signal handler crashed!");
            }
        }

        {
            let mut supervisor = worker.supervisor.write().unwrap();
            try!(supervisor.check_process());
        }

        let mut restart_process = false;

        // This section, and the following really need to be refactored:
        //
        // 1. We check to see if we are in an event a bunch of times
        // 2. We potentially restart 3 different times - twice for reconfigure, and once for
        //    file_udpated. That's pretty yucky.
        //
        // Love, Adam
        {
            // Manage the census
            let (write_census, in_event, write_rumor, me_clone) = {
                let cl = worker.census_list.read().unwrap();
                let census = cl.local_census();
                (cl.needs_write(), census.in_event, census.me().needs_write(), census.me().clone())
            };

            if write_census {
                if !in_event {
                    let mut service_config = worker.service_config.write().unwrap();
                    let cl = worker.census_list.read().unwrap();
                    service_config.svc(&cl);
                    service_config.bind(worker.config.bind(), &cl);
                }
                if write_rumor {
                    debug!("Writing our census rumor: {:#?}", me_clone);
                    let mut rl = worker.rumor_list.write().unwrap();
                    rl.add_rumor(Rumor::census_entry(me_clone));
                }
                let mut cl = worker.census_list.write().unwrap();
                cl.written();
            }

            // Don't bother trying to reconfigure if we are in an event - just wait till
            // everything settles down.
            {
                let census_list = worker.census_list.read().unwrap();
                let census = census_list.local_census();
                if !census.in_event {
                    let mut service_config = worker.service_config.write().unwrap();
                    if service_config.needs_write {
                        let package = worker.package.read().unwrap();
                        // Write the configuration, and restart if needed
                        if try!(service_config.write(&package)) {
                            try!(package.copy_run(&service_config));
                            try!(package.reconfigure(&service_config));
                            outputln!("Restarting because the service config was updated via the \
                                       census");
                            restart_process = true;
                        }
                    }
                }
            }
        }

        {
            let in_event = {
                let census_list = worker.census_list.read().unwrap();
                let census = census_list.local_census();
                census.in_event
            };
            let (needs_file_updated, needs_reconfigure) = if in_event {
                (false, false)
            } else {
                let mut gossip_file_list = worker.gossip_file_list.write().unwrap();
                let needs_write = {
                    gossip_file_list.needs_write()
                };
                if needs_write {
                    try!(gossip_file_list.write())
                } else {
                    (false, false)
                }
            };
            if needs_file_updated {
                let service_config = worker.service_config.read().unwrap();
                let package = worker.package.read().unwrap();
                let existed = try!(package.file_updated(&service_config));
                if !existed {
                    restart_process = true;
                }
            }
            if needs_reconfigure {
                let mut service_config = worker.service_config.write().unwrap();
                let package = worker.package.read().unwrap();
                service_config.cfg(&package);
                if try!(service_config.write(&package)) {
                    try!(package.copy_run(&service_config));
                    let existed = try!(package.reconfigure(&service_config));
                    if !existed {
                        restart_process = true;
                    }
                }
            }
        }

        if let Some(ref updater) = worker.pkg_updater {
            match updater.receiver.try_recv() {
                Ok(wonder::actor::Message::Cast(package::UpdaterMessage::Update(package))) => {
                    debug!("Main loop received package update notification: {:?}",
                           &package);
                    try!(worker.update_package(package));
                    try!(package::PackageUpdater::run(&updater));
                    // force the package to restart
                    outputln!("Restarting because the package was updated");
                    restart_process = true;
                }
                Ok(_) => {}
                Err(TryRecvError::Empty) => {}
                Err(TryRecvError::Disconnected) => {
                    panic!("package updater crashed!");
                }
            }
        }

        {
            let mut supervisor = worker.supervisor.write().unwrap();
            // If our target is that the process is up
            if supervisor.is_up() {
                // And no process is running
                if supervisor.pid.is_none() {
                    // Start a new one
                    try!(supervisor.start());
                } else {
                    // If we were supposed to restart
                    if restart_process {
                        // And we have ever started before...
                        if supervisor.has_started {
                            // Restart
                            try!(supervisor.restart());
                        }
                    }
                }
            }
        }

        // Next state!
        try!(sm.next(worker));

        // Slow down our loop
        let elapsed_time = SteadyTime::now() - start_time;
        let elapsed_millis = elapsed_time.num_milliseconds();

        if elapsed_millis < MINIMUM_LOOP_TIME_MS {
            thread::sleep(Duration::from_millis((MINIMUM_LOOP_TIME_MS - elapsed_millis) as u64));
        }
    }
    Ok(())
}
<|endoftext|>


<commit_before>
use serialize::json::Json;
use time::Timespec;

use std::sync::Arc;
use std::mem;

use from::{From, RcFrom, FromSelect};
use field::{Field, UntypedField};
use predicate::{
    RcPredicate,
    ToOrPredicate,
    ToAndPredicate,
    ToExcludePredicate
};
use to_sql::{ToSql};
use order_by::{OrderBy};
use join::{Join};

use field::{
    FieldDef,
    I8Comparable,
    I16Comparable,
    I32Comparable,
    I64Comparable,
    F32Comparable,
    F64Comparable,
    StringComparable,
    JsonComparable,
    TimespecComparable,

    I8ComparableList,
    I16ComparableList,
    I32ComparableList,
    I64ComparableList,
    F32ComparableList,
    F64ComparableList,
    StringComparableList,
    JsonComparableList,
    TimespecComparableList
};

#[deriving(Clone)]
pub enum Select {
    SelectOnly(Vec<FieldDef<()>>),
    SelectAll
}

pub trait ToSelectQuery: Send + Sync + ToSql {
    fn upcast(self) -> RcSelectQuery {
        Arc::new(box self as BoxedSelectQuery)
    }
}

#[deriving(Clone)]
pub struct LimitOne;

#[deriving(Clone)]
pub struct LimitTwo;

#[deriving(Clone)]
pub struct LimitMany;

#[deriving(Clone)]
pub struct SelectQuery<T, L, M> {
    pub select: Select,
    pub from: RcFrom,
    pub where_: Option<RcPredicate>,
    pub limit: Option<uint>,
    pub offset: Option<uint>,
    pub order_by: Vec<OrderBy>,
    pub joins: Vec<Join>
}

macro_rules! set_where(
    ($s:ident, $pr:expr, $w:ident, $new_pr:expr) => ({
        let mut query = $s.clone();
        match $s.get_where() {
            &Some(ref $w) => {
                query.set_where($new_pr);
            },
            &None => {
                query.set_where($pr);
            }
        }
        query
    })
)

pub trait Queryable: Clone {
    fn get_where(&self) -> &Option<RcPredicate>;
    fn set_where(&mut self, RcPredicate);
    fn unset_where(&mut self);

    fn or(&self, predicate: RcPredicate) -> Self {
        set_where!(self, predicate, w, w.or(predicate))
    }

    fn where_(&self, predicate: RcPredicate) -> Self {
        set_where!(self, predicate, w, w.and(predicate))
    }

    fn and(&self, predicate: RcPredicate) -> Self {
        self.where_(predicate)
    }

    fn exclude(&self, predicate: RcPredicate) -> Self {
       set_where!(self, predicate.exclude(), w, w.and(predicate.exclude()))
    }

    fn and_exclude(&self, predicate: RcPredicate) -> Self {
       self.exclude(predicate)
    }

    fn or_exclude(&self, predicate: RcPredicate) -> Self {
       set_where!(self, predicate.exclude(), w, w.or(predicate.exclude()))
    }

}

pub trait Orderable: Clone {
    fn get_order_by_mut(&mut self) -> &mut Vec<OrderBy>;
    fn set_order_by(&mut self, Vec<OrderBy>);

    fn order_by<F: Clone>(&self, field: &Field<F>) -> Self {
        let mut query = self.clone();
        query.set_order_by(
            vec![OrderBy::by(field)]
        );
        query
    }

    fn order_by_fields<F: Clone>(&self, fields: &[&Field<F>]) -> Self {
        let mut query = self.clone();
        query.set_order_by(
            fields.iter().map(|f| OrderBy::by(*f)).collect()
        );
        query
    }

    fn reverse_by<F: Clone>(&self, field: &Field<F>) -> Self {
        let mut query = self.clone();
        query.set_order_by(
            vec![OrderBy::reverse_by(field)]
        );
        query
    }

    fn reverse_by_fields<F: Clone>(&self, fields: &[&Field<F>]) -> Self {
        let mut query = self.clone();
        query.set_order_by(
            fields.iter().map(|f| OrderBy::reverse_by(*f)).collect()
        );
        query
    }

    fn order_append<F: Clone>(&self, field: &Field<F>) -> Self {
        let mut query = self.clone();
        query.get_order_by_mut().push(OrderBy::by(field));
        query
    }

    fn order_prepend<F: Clone>(&self, field: &Field<F>) -> Self {
        let mut query = self.clone();
        query.get_order_by_mut().insert(0, OrderBy::by(field));
        query
    }

    fn order_reverse_append<F: Clone>(&self, field: &Field<F>) -> Self {
        let mut query = self.clone();
        query.get_order_by_mut().push(OrderBy::reverse_by(field));
        query
    }

    fn order_reverse_prepend<F: Clone>(&self, field: &Field<F>) -> Self {
        let mut query = self.clone();
        query.get_order_by_mut().insert(0, OrderBy::reverse_by(field));
        query
    }

}

impl<T: Clone, L: Clone, M: Clone> SelectQuery<T, L, M> {

    pub fn new(select: Select, from: RcFrom) -> SelectQuery<T, L, M> {
        SelectQuery {
            select: select,
            from: from,
            where_: None,
            limit: None,
            offset: None,
            order_by: vec![],
            joins: vec![]
        }
    }

    pub fn limit(&self, limit: uint) -> SelectQuery<T, LimitOne, M> {
        let mut query = self.clone();
        query.limit = Some(limit);
        unsafe{ mem::transmute(query) }
    }

    pub fn first(&self) -> SelectQuery<T, LimitOne, M> {
        let mut query = self.clone();
        query.limit = Some(1);
        unsafe{ mem::transmute(query) }
    }

    pub fn last(&self) -> SelectQuery<T, LimitOne, M> {
        unimplemented!()
    }

    pub fn offset(&self, offset: uint) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.offset = Some(offset);
        query
    }

    pub fn alias(&self, alias: &str) -> FromSelect<T, L, M> {
        FromSelect { select: self.clone(), alias: alias.to_string() }
    }

    pub fn inner_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::inner_join(from.upcast_from(), on));
        query
    }

    pub fn full_outer_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::full_outer_join(from.upcast_from(), on));
        query
    }

    pub fn right_outer_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::right_outer_join(from.upcast_from(), on));
        query
    }

    pub fn left_outer_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::left_outer_join(from.upcast_from(), on));
        query
    }

    pub fn full_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::full_join(from.upcast_from(), on));
        query
    }

    pub fn left_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::left_join(from.upcast_from(), on));
        query
    }

    pub fn right_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::right_join(from.upcast_from(), on));
        query
    }

    pub fn natural_join(&self, from: &From) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::natural_join(from.upcast_from()));
        query
    }

    pub fn natural_left_join(&self, from: &From) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::natural_left_join(from.upcast_from()));
        query
    }

    pub fn natural_right_join(&self, from: &From) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::natural_right_join(from.upcast_from()));
        query
    }

    pub fn natural_full_join(&self, from: &From) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::natural_full_join(from.upcast_from()));
        query
    }

    pub fn cross_join(&self, from: &From) -> SelectQuery<T, L, M> {
        let mut query = self.clone();
        query.joins.push(Join::cross_join(from.upcast_from()));
        query
    }
}

pub trait Selectable<M: Clone>: From {
    // FIXME: Unify select_N after [generics](https://github.com/rust-lang/rfcs/issues/376)

    fn select_1<T: Clone>(&self, field: &Field<T>) -> SelectQuery<(T), LimitMany, M> {
        SelectQuery::new(SelectOnly(vec![field.to_def().clone_with_erase()]), self.upcast_from())
    }

    fn select_2<T1: Clone, T2: Clone>(&self, field1: &Field<T1>, field2: &Field<T2>) -> SelectQuery<(T1, T2), LimitMany, M> {
        SelectQuery::new(SelectOnly(vec![field1.to_def().clone_with_erase(), field2.to_def().clone_with_erase()]), self.upcast_from())
    }

    fn select(&self, fields: &[&UntypedField]) -> SelectQuery<(), LimitMany, M> {
        SelectQuery::new(SelectOnly(fields.iter().map(|f| f.to_def().clone_with_erase()).collect()), self.upcast_from())
    }

    fn select_all(&self) -> SelectQuery<(), LimitMany, M> {
        SelectQuery::new(SelectAll, self.upcast_from())
    }
}

impl<T: Clone, L: Clone, M: Clone> Queryable for SelectQuery<T, L, M> {
    fn get_where(&self) -> &Option<RcPredicate> { &self.where_ }
    fn set_where(&mut self, predicate: RcPredicate) { self.where_ = Some(predicate); }
    fn unset_where(&mut self) { self.where_ = None; }
}

impl<T: Clone, L: Clone, M: Clone> Orderable for SelectQuery<T, L, M> {
    fn get_order_by_mut(&mut self) -> &mut Vec<OrderBy> { &mut self.order_by }
    fn set_order_by(&mut self, order_by: Vec<OrderBy>) { self.order_by = order_by }
}

impl<T: Clone, L: Clone, M: Clone> ToSelectQuery for SelectQuery<T, L, M> { }

pub type BoxedSelectQuery = Box<ToSelectQuery + Send + Sync>;
pub type RcSelectQuery = Arc<BoxedSelectQuery>;

impl<M: Clone> I8Comparable for SelectQuery<(i8), LimitOne, M> { }
impl<M: Clone> I16Comparable for SelectQuery<(i16), LimitOne, M> { }
impl<M: Clone> I32Comparable for SelectQuery<(i32), LimitOne, M> { }
impl<M: Clone> I64Comparable for SelectQuery<(i64), LimitOne, M> { }
impl<M: Clone> F32Comparable for SelectQuery<(f32), LimitOne, M> { }
impl<M: Clone> F64Comparable for SelectQuery<(f64), LimitOne, M> { }
impl<M: Clone> StringComparable for SelectQuery<(String), LimitOne, M> { }
impl<M: Clone> JsonComparable for SelectQuery<(Json), LimitOne, M> { }
impl<M: Clone> TimespecComparable for SelectQuery<(Timespec), LimitOne, M> { }

impl<M: Clone> I8ComparableList for SelectQuery<(i8), LimitMany, M> { }
impl<M: Clone> I16ComparableList for SelectQuery<(i16), LimitMany, M> { }
impl<M: Clone> I32ComparableList for SelectQuery<(i32), LimitMany, M> { }
impl<M: Clone> I64ComparableList for SelectQuery<(i64), LimitMany, M> { }
impl<M: Clone> F32ComparableList for SelectQuery<(f32), LimitMany, M> { }
impl<M: Clone> F64ComparableList for SelectQuery<(f64), LimitMany, M> { }
impl<M: Clone> StringComparableList for SelectQuery<(String), LimitMany, M> { }
impl<M: Clone> JsonComparableList for SelectQuery<(Json), LimitMany, M> { }
impl<M: Clone> TimespecComparableList for SelectQuery<(Timespec), LimitMany, M> { }

<commit_msg>feat: impl `with_clone!` macro to reduce copy-paste in select_query<commit_after>
use serialize::json::Json;
use time::Timespec;

use std::sync::Arc;
use std::mem;

use from::{From, RcFrom, FromSelect};
use field::{Field, UntypedField};
use predicate::{
    RcPredicate,
    ToOrPredicate,
    ToAndPredicate,
    ToExcludePredicate
};
use to_sql::{ToSql};
use order_by::{OrderBy};
use join::{Join};

use field::{
    FieldDef,
    I8Comparable,
    I16Comparable,
    I32Comparable,
    I64Comparable,
    F32Comparable,
    F64Comparable,
    StringComparable,
    JsonComparable,
    TimespecComparable,

    I8ComparableList,
    I16ComparableList,
    I32ComparableList,
    I64ComparableList,
    F32ComparableList,
    F64ComparableList,
    StringComparableList,
    JsonComparableList,
    TimespecComparableList
};

#[deriving(Clone)]
pub enum Select {
    SelectOnly(Vec<FieldDef<()>>),
    SelectAll
}

pub trait ToSelectQuery: Send + Sync + ToSql {
    fn upcast(self) -> RcSelectQuery {
        Arc::new(box self as BoxedSelectQuery)
    }
}

#[deriving(Clone)]
pub struct LimitOne;

#[deriving(Clone)]
pub struct LimitTwo;

#[deriving(Clone)]
pub struct LimitMany;

#[deriving(Clone)]
pub struct SelectQuery<T, L, M> {
    pub select: Select,
    pub from: RcFrom,
    pub where_: Option<RcPredicate>,
    pub limit: Option<uint>,
    pub offset: Option<uint>,
    pub order_by: Vec<OrderBy>,
    pub joins: Vec<Join>
}

macro_rules! set_where(
    ($s:ident, $pr:expr, $w:ident, $new_pr:expr) => ({
        let mut query = $s.clone();
        match $s.get_where() {
            &Some(ref $w) => {
                query.set_where($new_pr);
            },
            &None => {
                query.set_where($pr);
            }
        }
        query
    })
)

pub trait Queryable: Clone {
    fn get_where(&self) -> &Option<RcPredicate>;
    fn set_where(&mut self, RcPredicate);
    fn unset_where(&mut self);

    fn or(&self, predicate: RcPredicate) -> Self {
        set_where!(self, predicate, w, w.or(predicate))
    }

    fn where_(&self, predicate: RcPredicate) -> Self {
        set_where!(self, predicate, w, w.and(predicate))
    }

    fn and(&self, predicate: RcPredicate) -> Self {
        self.where_(predicate)
    }

    fn exclude(&self, predicate: RcPredicate) -> Self {
       set_where!(self, predicate.exclude(), w, w.and(predicate.exclude()))
    }

    fn and_exclude(&self, predicate: RcPredicate) -> Self {
       self.exclude(predicate)
    }

    fn or_exclude(&self, predicate: RcPredicate) -> Self {
       set_where!(self, predicate.exclude(), w, w.or(predicate.exclude()))
    }

}

macro_rules! with_clone(
    ($slf: ident, $v:ident, $ex:expr) => ({
        let mut $v = $slf.clone();
        $ex;
        $v
    })
)

pub trait Orderable: Clone {
    fn get_order_by_mut(&mut self) -> &mut Vec<OrderBy>;
    fn set_order_by(&mut self, Vec<OrderBy>);

    fn order_by<F: Clone>(&self, field: &Field<F>) -> Self {
        with_clone!(self, query, query.set_order_by(
            vec![OrderBy::by(field)]
        ))
    }

    fn order_by_fields<F: Clone>(&self, fields: &[&Field<F>]) -> Self {
        with_clone!(self, query, query.set_order_by(
            fields.iter().map(|f| OrderBy::by(*f)).collect()
        ))
    }

    fn reverse_by<F: Clone>(&self, field: &Field<F>) -> Self {
        with_clone!(self, query, query.set_order_by(
            vec![OrderBy::reverse_by(field)]
        ))
    }

    fn reverse_by_fields<F: Clone>(&self, fields: &[&Field<F>]) -> Self {
        with_clone!(self, query, query.set_order_by(
            fields.iter().map(|f| OrderBy::reverse_by(*f)).collect()
        ))
    }

    fn order_append<F: Clone>(&self, field: &Field<F>) -> Self {
        with_clone!(self, query, query.get_order_by_mut().push(OrderBy::by(field)))
    }

    fn order_prepend<F: Clone>(&self, field: &Field<F>) -> Self {
        with_clone!(self, query, query.get_order_by_mut().insert(0, OrderBy::by(field)))
    }

    fn order_reverse_append<F: Clone>(&self, field: &Field<F>) -> Self {
        with_clone!(self, query, query.get_order_by_mut().push(OrderBy::reverse_by(field)))
    }

    fn order_reverse_prepend<F: Clone>(&self, field: &Field<F>) -> Self {
        with_clone!(self, query, query.get_order_by_mut().insert(0, OrderBy::reverse_by(field)))
    }

}

impl<T: Clone, L: Clone, M: Clone> SelectQuery<T, L, M> {

    pub fn new(select: Select, from: RcFrom) -> SelectQuery<T, L, M> {
        SelectQuery {
            select: select,
            from: from,
            where_: None,
            limit: None,
            offset: None,
            order_by: vec![],
            joins: vec![]
        }
    }

    pub fn limit(&self, limit: uint) -> SelectQuery<T, LimitOne, M> {
        let mut query = self.clone();
        query.limit = Some(limit);
        unsafe{ mem::transmute(query) }
    }

    pub fn first(&self) -> SelectQuery<T, LimitOne, M> {
        let mut query = self.clone();
        query.limit = Some(1);
        unsafe{ mem::transmute(query) }
    }

    pub fn offset(&self, offset: uint) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.offset = Some(offset))
    }

    pub fn alias(&self, alias: &str) -> FromSelect<T, L, M> {
        FromSelect { select: self.clone(), alias: alias.to_string() }
    }

    pub fn inner_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::inner_join(from.upcast_from(), on)))
    }

    pub fn full_outer_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::full_outer_join(from.upcast_from(), on)))
    }

    pub fn right_outer_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::right_outer_join(from.upcast_from(), on)))
    }

    pub fn left_outer_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::left_outer_join(from.upcast_from(), on)))
    }

    pub fn full_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::full_join(from.upcast_from(), on)))
    }

    pub fn left_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::left_join(from.upcast_from(), on)))
    }

    pub fn right_join(&self, from: &From, on: RcPredicate) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::right_join(from.upcast_from(), on)))
    }

    pub fn natural_join(&self, from: &From) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::natural_join(from.upcast_from())))
    }

    pub fn natural_left_join(&self, from: &From) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::natural_left_join(from.upcast_from())))
    }

    pub fn natural_right_join(&self, from: &From) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::natural_right_join(from.upcast_from())))
    }

    pub fn natural_full_join(&self, from: &From) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::natural_full_join(from.upcast_from())))
    }

    pub fn cross_join(&self, from: &From) -> SelectQuery<T, L, M> {
        with_clone!(self, query, query.joins.push(Join::cross_join(from.upcast_from())))
    }
}

pub trait Selectable<M: Clone>: From {
    // FIXME: Unify select_N after [generics](https://github.com/rust-lang/rfcs/issues/376)

    fn select_1<T: Clone>(&self, field: &Field<T>) -> SelectQuery<(T), LimitMany, M> {
        SelectQuery::new(SelectOnly(vec![field.to_def().clone_with_erase()]), self.upcast_from())
    }

    fn select_2<T1: Clone, T2: Clone>(&self, field1: &Field<T1>, field2: &Field<T2>) -> SelectQuery<(T1, T2), LimitMany, M> {
        SelectQuery::new(SelectOnly(vec![field1.to_def().clone_with_erase(), field2.to_def().clone_with_erase()]), self.upcast_from())
    }

    fn select(&self, fields: &[&UntypedField]) -> SelectQuery<(), LimitMany, M> {
        SelectQuery::new(SelectOnly(fields.iter().map(|f| f.to_def().clone_with_erase()).collect()), self.upcast_from())
    }

    fn select_all(&self) -> SelectQuery<(), LimitMany, M> {
        SelectQuery::new(SelectAll, self.upcast_from())
    }
}

impl<T: Clone, L: Clone, M: Clone> Queryable for SelectQuery<T, L, M> {
    fn get_where(&self) -> &Option<RcPredicate> { &self.where_ }
    fn set_where(&mut self, predicate: RcPredicate) { self.where_ = Some(predicate); }
    fn unset_where(&mut self) { self.where_ = None; }
}

impl<T: Clone, L: Clone, M: Clone> Orderable for SelectQuery<T, L, M> {
    fn get_order_by_mut(&mut self) -> &mut Vec<OrderBy> { &mut self.order_by }
    fn set_order_by(&mut self, order_by: Vec<OrderBy>) { self.order_by = order_by }
}

impl<T: Clone, L: Clone, M: Clone> ToSelectQuery for SelectQuery<T, L, M> { }

pub type BoxedSelectQuery = Box<ToSelectQuery + Send + Sync>;
pub type RcSelectQuery = Arc<BoxedSelectQuery>;

impl<M: Clone> I8Comparable for SelectQuery<(i8), LimitOne, M> { }
impl<M: Clone> I16Comparable for SelectQuery<(i16), LimitOne, M> { }
impl<M: Clone> I32Comparable for SelectQuery<(i32), LimitOne, M> { }
impl<M: Clone> I64Comparable for SelectQuery<(i64), LimitOne, M> { }
impl<M: Clone> F32Comparable for SelectQuery<(f32), LimitOne, M> { }
impl<M: Clone> F64Comparable for SelectQuery<(f64), LimitOne, M> { }
impl<M: Clone> StringComparable for SelectQuery<(String), LimitOne, M> { }
impl<M: Clone> JsonComparable for SelectQuery<(Json), LimitOne, M> { }
impl<M: Clone> TimespecComparable for SelectQuery<(Timespec), LimitOne, M> { }

impl<M: Clone> I8ComparableList for SelectQuery<(i8), LimitMany, M> { }
impl<M: Clone> I16ComparableList for SelectQuery<(i16), LimitMany, M> { }
impl<M: Clone> I32ComparableList for SelectQuery<(i32), LimitMany, M> { }
impl<M: Clone> I64ComparableList for SelectQuery<(i64), LimitMany, M> { }
impl<M: Clone> F32ComparableList for SelectQuery<(f32), LimitMany, M> { }
impl<M: Clone> F64ComparableList for SelectQuery<(f64), LimitMany, M> { }
impl<M: Clone> StringComparableList for SelectQuery<(String), LimitMany, M> { }
impl<M: Clone> JsonComparableList for SelectQuery<(Json), LimitMany, M> { }
impl<M: Clone> TimespecComparableList for SelectQuery<(Timespec), LimitMany, M> { }

<|endoftext|>