Shared Rust kernels
ported/dynamic_array_reshape_family
All modules · quoted at commit 9e1884369a67 of DnaCalc/DnaCalc. Comments are the source's own.
coerce_prepared_to_number · 7 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHub/// A prepared scalar as a number, by worksheet number coercion (a blank is 0).
pub(crate) fn coerce_prepared_to_number(value: &CalcValue) -> Result<f64, CoercionError> {
match coerce::number(value)? {
Numeric::Number(n) => Ok(n),
Numeric::Decimal(decimal) => Ok(decimal.nearest()?),
}
}
Used by 14 functions.
scalar_cell · 11 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn scalar_cell(arg: &CalcValue) -> CalcValue {
match arg.core_ref() {
CoreRef::Number(n) => CalcValue::number(n),
CoreRef::Text(t) => CalcValue::text(t.clone()),
CoreRef::Logical(b) => CalcValue::logical(b),
CoreRef::Error(code) => CalcValue::error(code),
CoreRef::Reference(_) => CalcValue::error(WorksheetErrorCode::Value),
CoreRef::Array(_) => CalcValue::error(WorksheetErrorCode::Value),
CoreRef::Missing | CoreRef::Empty => CalcValue::empty(),
}
}
Used by 11 functions.
materialize_array_arg · 6 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn materialize_array_arg(arg: &CalcValue) -> CalcArray {
match arg.core_ref() {
CoreRef::Array(array) => array.clone(),
_ => CalcArray::from_scalar(scalar_cell(arg)),
}
}
Used by 10 functions.
shape · 6 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn shape(&self) -> ArrayShape {
match self {
Self::Array(array) => array.shape(),
Self::Scalar(_) => ArrayShape { rows: 1, cols: 1 },
}
}
Used by 12 functions.
get · 7 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn get(&self, row: usize, col: usize) -> Option<&CalcValue> {
match self {
Self::Array(array) => array.get(row, col),
Self::Scalar(cell) if row == 0 && col == 0 => Some(cell),
Self::Scalar(_) => None,
}
}
Used by 12 functions.
parse_integer · 12 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubpub(crate) fn parse_integer(prepared: &CalcValue) -> Result<isize, DynamicArrayReshapeEvalError> {
let raw =
coerce_prepared_to_number(prepared).map_err(DynamicArrayReshapeEvalError::Preparation)?;
if !raw.is_finite() {
return Err(DynamicArrayReshapeEvalError::InvalidCount);
}
let truncated = raw.trunc();
if (truncated - raw).abs() > f64::EPSILON {
return Err(DynamicArrayReshapeEvalError::InvalidCount);
}
Ok(truncated as isize)
}
Used by 9 functions.
parse_positive_integer · 7 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn parse_positive_integer(prepared: &CalcValue) -> Result<usize, DynamicArrayReshapeEvalError> {
let value = parse_integer(prepared)?;
if value < 1 {
return Err(DynamicArrayReshapeEvalError::InvalidCount);
}
Ok(value as usize)
}
Used by 3 functions.
parse_bool_like · 13 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn parse_bool_like(prepared: &CalcValue) -> Result<bool, DynamicArrayReshapeEvalError> {
match prepared.core_ref() {
CoreRef::Logical(b) => Ok(b),
CoreRef::Number(n) => Ok(n != 0.0),
CoreRef::Empty | CoreRef::Missing => Ok(false),
CoreRef::Error(code) => Err(DynamicArrayReshapeEvalError::Preparation(
CoercionError::WorksheetError(code),
)),
_ => Err(DynamicArrayReshapeEvalError::Preparation(
CoercionError::UnsupportedValueKind("boolean_like"),
)),
}
}
Used by 2 functions.
resolve_selector · 18 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn resolve_selector(index: isize, len: usize) -> Result<usize, DynamicArrayReshapeEvalError> {
if index == 0 {
return Err(DynamicArrayReshapeEvalError::InvalidSelector);
}
let resolved = if index > 0 {
(index - 1) as usize
} else {
let offset = len as isize + index;
if offset < 0 {
return Err(DynamicArrayReshapeEvalError::InvalidSelector);
}
offset as usize
};
if resolved >= len {
return Err(DynamicArrayReshapeEvalError::InvalidSelector);
}
Ok(resolved)
}
Used by 2 functions.
build_array · 9 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn build_array(
rows: usize,
cols: usize,
cells: Vec<CalcValue>,
) -> Result<CalcValue, DynamicArrayReshapeEvalError> {
CalcArray::new(ArrayShape { rows, cols }, cells)
.map(CalcValue::array)
.ok_or(DynamicArrayReshapeEvalError::EmptyArrayResult)
}
Used by 13 functions.
flatten_cells · 13 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn flatten_cells(array: &CalcArray, by_col: bool) -> Vec<CalcValue> {
if !by_col {
return array.iter_row_major().cloned().collect();
}
let mut cells = Vec::with_capacity(array.shape().rows * array.shape().cols);
for col in 0..array.shape().cols {
for row in 0..array.shape().rows {
cells.push(array.get(row, col).expect("validated cell").clone());
}
}
cells
}
Used by 4 functions.
take_span · 12 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubpub(crate) fn take_span(len: usize, count: isize) -> Result<(usize, usize), DynamicArrayReshapeEvalError> {
if count == 0 {
return Err(DynamicArrayReshapeEvalError::EmptyArrayResult);
}
if count > 0 {
let take = usize::min(count as usize, len);
Ok((0, take))
} else {
let take = usize::min((-count) as usize, len);
Ok((len - take, len))
}
}
Used by 2 functions.
drop_span · 11 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubpub(crate) fn drop_span(len: usize, count: isize) -> Result<(usize, usize), DynamicArrayReshapeEvalError> {
let (start, end) = if count >= 0 {
(usize::min(count as usize, len), len)
} else {
(0, len.saturating_sub((-count) as usize))
};
if start >= end {
return Err(DynamicArrayReshapeEvalError::EmptyArrayResult);
}
Ok((start, end))
}
Used by 2 functions.
should_ignore_cell · 12 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn should_ignore_cell(cell: &CalcValue, ignore_mode: usize) -> bool {
match ignore_mode {
0 => false,
1 => matches!(cell.core_ref(), CoreRef::Empty | CoreRef::Missing),
2 => matches!(cell.core_ref(), CoreRef::Error(_)),
3 => matches!(
cell.core_ref(),
CoreRef::Empty | CoreRef::Missing | CoreRef::Error(_)
),
_ => false,
}
}
Used by 2 functions.
parse_ignore_mode · 13 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn parse_ignore_mode(arg: Option<&CalcValue>) -> Result<usize, DynamicArrayReshapeEvalError> {
let Some(arg) = arg else {
return Ok(0);
};
if matches!(arg.core_ref(), CoreRef::Missing | CoreRef::Empty) {
return Ok(0);
}
let mode = parse_integer(arg)?;
if !(0..=3).contains(&mode) {
return Err(DynamicArrayReshapeEvalError::InvalidIgnoreMode);
}
Ok(mode as usize)
}
Used by 2 functions.
wrap_count · 11 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHub/// Wrapping has its own below-one error; other shaping counts keep their existing policy.
fn wrap_count(value: &CalcValue) -> Result<usize, DynamicArrayReshapeEvalError> {
let number = coerce_prepared_to_number(value)
.map_err(DynamicArrayReshapeEvalError::Preparation)?;
if number < 1.0 {
return Err(DynamicArrayReshapeEvalError::Preparation(
CoercionError::WorksheetError(WorksheetErrorCode::Num),
));
}
parse_positive_integer(value)
}
Used by 2 functions.
wrap_vector · 9 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubfn wrap_vector(value: &CalcValue) -> Result<CalcArray, DynamicArrayReshapeEvalError> {
let source = materialize_array_arg(value);
if source.shape().rows > 1 && source.shape().cols > 1 {
return Err(DynamicArrayReshapeEvalError::Preparation(
CoercionError::UnsupportedValueKind("wrap vector"),
));
}
Ok(source)
}
Used by 2 functions.
map_dynamic_array_reshape_error_to_ws · 20 lines · calc-func/src/ported/dynamic_array_reshape_family.rs on GitHubpub fn map_dynamic_array_reshape_error_to_ws(
error: &DynamicArrayReshapeEvalError,
) -> WorksheetErrorCode {
match error {
DynamicArrayReshapeEvalError::ArityMismatch { .. }
| DynamicArrayReshapeEvalError::InvalidSelector
| DynamicArrayReshapeEvalError::InvalidCount
| DynamicArrayReshapeEvalError::InvalidIgnoreMode
| DynamicArrayReshapeEvalError::InvalidSortOrder
| DynamicArrayReshapeEvalError::InvalidSortIndex
| DynamicArrayReshapeEvalError::InvalidIncludeShape
| DynamicArrayReshapeEvalError::Preparation(CoercionError::UnsupportedValueKind(_))
| DynamicArrayReshapeEvalError::Preparation(CoercionError::NotModelled) => {
WorksheetErrorCode::Value
}
DynamicArrayReshapeEvalError::Preparation(CoercionError::WorksheetError(code)) => *code,
DynamicArrayReshapeEvalError::EmptyArrayResult => WorksheetErrorCode::Calc,
DynamicArrayReshapeEvalError::DimensionTooSmall => WorksheetErrorCode::Value,
}
}
Used by 13 functions.