Skip to content

Commit

Permalink
Add some more extension validator functions
Browse files Browse the repository at this point in the history
  • Loading branch information
apjanke committed Sep 12, 2020
1 parent 93b44ef commit 2cca2ac
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 8 deletions.
13 changes: 7 additions & 6 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
Validoozy change history
========================

v1.1.0 ???
v 1.1.0 ???
-----------------
* Add mustBeCompatibleSizes
* Allow mustBeSameSize to take any number of inputs
* Add error identifiers
* Bug fixes in input checking of label arguments
* Add some more validator functions

v1.0.2 2019-04-28
-----------------
v 1.0.2 2019-04-28
------------------
* Minor doco changes

v1.0.1 2019-04-28
-----------------
v 1.0.1 2019-04-28
------------------
* Minor doco changes

v1.0.0 2019-04-28
v 1.0.0 2019-04-28
------------------
* Initial public release
6 changes: 6 additions & 0 deletions Mcode/extend/isstringy.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
function out = isstringy(x)
% True if input is a string-like value

out = iscellstr(x) || ischar(x) || isstring(x);

end
6 changes: 4 additions & 2 deletions Mcode/extend/mustBeCharvec.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ function mustBeCharvec (x, label)
% mustBeCharvec (x, label)
%
% Raises an error if the input x is not a row vector of chars.
% char row vectors are Octave's normal representation of single strings.
% char row vectors are Matlab's normal representation of single strings.
% (In older versions of Matlab.)
% (They are what are produced by '...' string literals.) As a special
% case, 0-by-0 empty chars (what is produced by the string literal '')
% case, 0-by-0 empty chars (what is produced by the char literal '')
% are also considered charvecs.
%
% label is an optional input that determines how the input will be described in
Expand All @@ -26,4 +27,5 @@ function mustBeCharvec (x, label)
'%s must be a char row vector; got a %s %s', ...
label, size2str(size(x)), class(x));
end

end
1 change: 1 addition & 0 deletions Mcode/extend/mustBeCompatibleSizes.m
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,5 @@ function mustBeCompatibleSizes(varargin)
end
end
end

end
22 changes: 22 additions & 0 deletions Mcode/extend/mustBeMatrix.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function x = mustBeMatrix(x, label)
%MUSTBEMATRIX Require that input is 2-dimensional
%
% mustBeMatrix(x, label)
%
% Requires that input x has exactly 2 dimensions, as determined by ismatrix(x).

if nargin < 2; label = []; end

if ~ismatrix(x)
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
error('validoozy:validators:SizeError', ...
'%s must be a matrix; got a %d-D array (%s)', label, ...
numel(size(x)), size2str(size(x)));
end

end
38 changes: 38 additions & 0 deletions Mcode/extend/mustBeMemberI.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
function x = mustBeMemberI(x, valid, label)
%MUSTBEMEMBERI Require input to be one of a list of valid values, case-insensitive
%
% x = mustBeMemberI(x, valid, label)
%
% Requires that all input elements are members of a given set of valid values,
% using case-insensitive comparison. Inputs must be string-y. ismember(lower(x),
% lower(valid)) is used to test membership.
%
% X is the input to check. It may be an array of multiple values.
%
% Valid is an array containing the valid values.
%
% If x is a char and valid is a cellstr, membership is tested stringwise. If x
% is a char and valid is a char, membership is tested characterwise. That means
% you probably want to always supply valid as a cellstr, not a charvec.

if nargin < 3; label = []; end
tf = ismember(lower(x), lower(valid));
if ~all(tf)
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
ix_bad = find(~tf);
if numel(ix_bad) > 1
term = 'values';
else
term = 'value';
end
x = cellstr(x);
error('validoozy:validators:ValueError', ...
'Invalid %s for %s: %s. Valid values are: %s (case-insensitive)', ...
term, label, strjoin(x(ix_bad), ', '), strjoin(valid, ', '));
end
end
25 changes: 25 additions & 0 deletions Mcode/extend/mustBeNameValueList.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
function x = mustBeNameValueList(x, label)
%MUSTBENAMEVALUELIST Require input to be a name/value cell vector list
%
% x = mustBeNameValueList(x, label)
%
% Requires that the input is a 2-N long cell vector containing name/value
% pairs. The "name" elements must be chars.

if nargin < 2; label = []; end

isNameValList = iscell(x) && (isvector(x) || isempty(x)) && (rem(numel(x), 2) == 0) ...
&& iscellstr(x(1:2:end));
if ~isNameValList
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
error('validoozy:validators:TypeError', ...
'%s must be a name/value cell vector; got a %s %s', ...
label, size2str(size(x)), class(x));
end

end
20 changes: 20 additions & 0 deletions Mcode/extend/mustBeNonNan.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
function mustBeNonNan(x, label)
%MUSTBENONNAN Require that input does not have any NaN values

if nargin < 2; label = []; end

tfNan = isnan(x(:));
if any(tfNan)
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
ixNan = find(tfNan);
error('validoozy:validators:InvalidInput', ...
'%s must be non-NaN; found a NaN in element %s', ...
label, ixNan(1));
end

end
18 changes: 18 additions & 0 deletions Mcode/extend/mustBeNonmissing.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
function mustBeNonmissing(x, label)
% Require input to be all non-missing

if nargin < 2; label = []; end

if any(ismissing(x))
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
error('validoozy:validators:ValueError', ...
'%s must be non-missing', ...
label);
end

end
17 changes: 17 additions & 0 deletions Mcode/extend/mustBeScalarNumeric.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function mustBeScalarNumeric(x, label)
%MUSTBESCALARNUMERIC Require that input is a scalar numeric

if nargin < 2; label = []; end

if ~(isscalar(x) && isnumeric(x))
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
error('validoozy:validators:TypeError', ...
'%s must be a scalar numeric; got a %s %s', ...
label, size2str(size(x)), class(x));
end
end
22 changes: 22 additions & 0 deletions Mcode/extend/mustBeScalarNumericOrEmpty.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
function x = mustBeScalarNumericOrEmpty(x, label)
%MUSTBESCALARNUMERICOREMPTY Require that input is a scalar numeric

if nargin < 2; label = []; end

if isempty(x)
return
end

if ~(isscalar(x) && isnumeric(x))
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
error('validoozy:validators:TypeError', ...
'%s must be a scalar numeric or empty; got a %s %s', ...
label, size2str(size(x)), class(x));
end

end
16 changes: 16 additions & 0 deletions Mcode/extend/mustBeScalarStruct.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
function x = mustBeScalarStruct(x, label)
if nargin < 2; label = []; end

if ~(isscalar(x) && isstruct(x))
if isempty(label)
label = inputname(1);
end
if isempty(label)
label = 'input';
end
error('validoozy:validators:TypeError', ...
'%s must be a scalar struct; got a %s %s', ...
label, size2str(size(x)), class(x));
end

end
27 changes: 27 additions & 0 deletions Mcode/extend/mustHaveFields.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function mustHaveFields(x, requiredFieldNames, label)
%MUSTHAVEFIELDS Require that input has given fields
%
% mustHaveFields(x, requiredFieldNames, label)
%
% Requires that input x has at least the fields named in requiredFieldNames, as
% determined by fieldnames(x). Extra fields are not an error, and are silently
% ignored.

fields = fieldnames(x);
tf = ismember(requiredFieldNames, fields);
if ~all(tf)
if nargin < 3 || isempty(label)
label = inputname(1);
end
if isempty(label)
valueLabel = 'Input';
else
valueLabel = sprintf('Input ''%s''', label);
end
missingFields = requiredFieldNames(~tf);
error('validoozy:InvalidInput', '%s is missing required fields: %s', ...
valueLabel, strjoin(missingFields));
end

end

0 comments on commit 2cca2ac

Please sign in to comment.