using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using GitHub.DistributedTask.Expressions; using Newtonsoft.Json.Linq; namespace GitHub.DistributedTask.Pipelines.Expressions { [EditorBrowsable(EditorBrowsableState.Never)] public sealed class LengthNode : FunctionNode { protected sealed override Boolean TraceFullyRealized => false; public static Int32 minParameters = 1; public static Int32 maxParameters = 1; protected sealed override Object EvaluateCore(EvaluationContext context) { // Length(value: object) var evaluationResult = Parameters[0].Evaluate(context); bool kindNotSupported = false; Int32 length = -1; switch (evaluationResult.Kind) { case ValueKind.Array: length = ((JArray)evaluationResult.Value).Count; break; case ValueKind.String: length = ((String)evaluationResult.Value).Length; break; case ValueKind.Object: if (evaluationResult.Value is IReadOnlyDictionary) { length = ((IReadOnlyDictionary)evaluationResult.Value).Count; } else if (evaluationResult.Value is ICollection) { length = ((ICollection)evaluationResult.Value).Count; } else { kindNotSupported = true; } break; case ValueKind.Boolean: case ValueKind.Null: case ValueKind.Number: case ValueKind.Version: kindNotSupported = true; break; } if (kindNotSupported) { throw new NotSupportedException(PipelineStrings.InvalidTypeForLengthFunction(evaluationResult.Kind)); } return new Decimal(length); } } }