git.delta.rocks / jrsonnet / refs/commits / 84fe36c05a1e

difftreelog

build missing sort

Lach2020-08-23parent: #a5391ab.patch.diff
in: master

1 file changed

addedcrates/jrsonnet-evaluator/src/builtin/sort.rsdiffbeforeafterboth
after · crates/jrsonnet-evaluator/src/builtin/sort.rs
1use crate::{2	error::{Error, LocError, Result},3	throw, Context, FuncVal, Val,4};5use std::rc::Rc;67#[derive(Debug, Clone)]8pub enum SortError {9	SortKeyShouldBeStringOrNumber,10	SortElementsShouldHaveEqualType,11}1213impl From<SortError> for LocError {14	fn from(s: SortError) -> Self {15		Self::new(Error::Sort(s))16	}17}1819#[derive(Copy, Clone)]20enum SortKeyType {21	Number,22	String,23	Unknown,24}2526#[derive(PartialEq)]27struct NonNaNF64(f64);28impl PartialOrd for NonNaNF64 {29	fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {30		self.0.partial_cmp(&other.0)31	}32}33impl Eq for NonNaNF64 {}34impl Ord for NonNaNF64 {35	fn cmp(&self, other: &Self) -> std::cmp::Ordering {36		self.partial_cmp(other).expect("non nan")37	}38}3940fn get_sort_type<T>(41	values: &mut Vec<T>,42	key_getter: impl Fn(&mut T) -> &mut Val,43) -> Result<SortKeyType> {44	let mut sort_type = SortKeyType::Unknown;45	for i in values.iter_mut() {46		let i = key_getter(i);47		i.inplace_unwrap()?;48		match (i, sort_type) {49			(Val::Str(_), SortKeyType::Unknown) => sort_type = SortKeyType::String,50			(Val::Num(_), SortKeyType::Unknown) => sort_type = SortKeyType::Number,51			(Val::Str(_), SortKeyType::String) => {}52			(Val::Str(_), _) => throw!(SortError::SortElementsShouldHaveEqualType),53			(Val::Num(_), SortKeyType::Number) => {}54			(Val::Num(_), _) => throw!(SortError::SortElementsShouldHaveEqualType),55			_ => throw!(SortError::SortKeyShouldBeStringOrNumber),56		}57	}58	Ok(sort_type)59}6061pub fn sort(ctx: Context, mut values: Rc<Vec<Val>>, key_getter: &FuncVal) -> Result<Rc<Vec<Val>>> {62	if values.len() <= 1 {63		return Ok(values);64	}65	if key_getter.is_ident() {66		let mvalues = Rc::make_mut(&mut values);67		let sort_type = get_sort_type(mvalues, |k| k)?;68		match sort_type {69			SortKeyType::Number => mvalues.sort_by_key(|v| match v {70				Val::Num(n) => NonNaNF64(*n),71				_ => unreachable!(),72			}),73			SortKeyType::String => mvalues.sort_by_key(|v| match v {74				Val::Str(s) => s.clone(),75				_ => unreachable!(),76			}),77			SortKeyType::Unknown => unreachable!(),78		};79		Ok(values)80	} else {81		let mut vk = Vec::with_capacity(values.len());82		for value in values.iter() {83			vk.push((84				value.clone(),85				key_getter.evaluate_values(ctx.clone(), &[value.clone()])?,86			));87		}88		let sort_type = get_sort_type(&mut vk, |v| &mut v.1)?;89		match sort_type {90			SortKeyType::Number => vk.sort_by_key(|v| match v.1 {91				Val::Num(n) => NonNaNF64(n),92				_ => unreachable!(),93			}),94			SortKeyType::String => vk.sort_by_key(|v| match &v.1 {95				Val::Str(s) => s.clone(),96				_ => unreachable!(),97			}),98			SortKeyType::Unknown => unreachable!(),99		};100		Ok(Rc::new(vk.into_iter().map(|v| v.0).collect()))101	}102}