/// <summary> /// Parse scalar /// </summary> /// <param name="context"></param> /// <returns></returns> private JsonToken ParseScalarLiteralValue(FilterParser.Scalar_literalContext context) { if (context.BOOLEAN() != null) { return(VariantValue.FromObject(bool.Parse(context.BOOLEAN().GetText()))); } if (context.NUMERIC_LITERAL() != null) { return(VariantValue.FromObject(double.Parse(context.NUMERIC_LITERAL().GetText(), CultureInfo.InvariantCulture))); } if (context.STRING_LITERAL() != null) { return(VariantValue.FromObject(ParseStringValue(context.STRING_LITERAL()))); } return(null); }
/// <inheritdoc/> public Variant Decode(VariantValue value, BuiltInType builtinType) { if (VariantValueEx.IsNull(value)) { return(Variant.Null); } // // Sanitize json input from user // value = Sanitize(value, builtinType == BuiltInType.String); VariantValue json; if (builtinType == BuiltInType.Null || (builtinType == BuiltInType.Variant && value.IsObject)) { // // Let the decoder try and decode the json variant. // json = Serializer.FromObject(new { value }); } else { // // Give decoder a hint as to the type to use to decode. // json = Serializer.FromObject(new { value = new { Body = value, Type = (byte)builtinType } }); } // // Decode json to a real variant // using (var text = new StringReader(Serializer.SerializeToString(json))) using (var reader = new Newtonsoft.Json.JsonTextReader(text)) using (var decoder = new JsonDecoderEx(reader, Context)) { return(decoder.ReadVariant(nameof(value))); } }
/// <summary> /// Initializes a new instance of the <see cref="ObjectSubtypeCriterion"/> class. /// </summary> /// <param name="attribute">The attribute that the criterion is based on.</param> /// <param name="attributeValue">The attribute value.</param> /// <param name="valueType">Type of the value.</param> public ObjectSubtypeCriterion([NotNull] ObjectAttribute attribute, [CanBeNull] object attributeValue, VariantValueType valueType = VariantValueType.Null) { Assert.ArgumentNotNull(attribute, nameof(attribute)); _attribute = attribute; if (valueType == VariantValueType.Null) { // attributeValue = null; // "" can not be cast to numeric _attributeValue = VariantValueFactory.Create(attribute, attributeValue); } else { _attributeValue = new VariantValue(attributeValue, valueType); } }
public async Task NodeWriteStaticScalarExpandedNodeIdValueVariableTestAsync() { var browser = _services(); var node = "http://test.org/UA/Data/#i=10233"; VariantValue expected = "http://opcfoundation.org/UA/Diagnostics#i=1375605653"; // Act var result = await browser.NodeValueWriteAsync(_endpoint, new ValueWriteRequestModel { NodeId = node, Value = expected, DataType = "ExpandedNodeId" }); // Assert await AssertResultAsync(node, expected, result); }
public async Task NodeWriteStaticScalarNodeIdValueVariableTestAsync() { var browser = _services(); var node = "http://test.org/UA/Data/#i=10232"; VariantValue expected = "http://samples.org/UA/memorybuffer#i=2040578002"; // Act var result = await browser.NodeValueWriteAsync(_endpoint, new ValueWriteRequestModel { NodeId = node, Value = expected, DataType = "NodeId" }); // Assert await AssertResultAsync(node, expected, result); }
public async Task NodeWriteStaticScalarGuidValueVariableTestAsync() { var browser = _services(); var node = "http://test.org/UA/Data/#i=10229"; VariantValue expected = "bdc1d303-2355-6173-9314-1816b7315b96"; // Act var result = await browser.NodeValueWriteAsync(_endpoint, new ValueWriteRequestModel { NodeId = node, Value = expected, DataType = "Guid" }); // Assert await AssertResultAsync(node, expected, result); }
/// <summary> /// Parse string function /// </summary> /// <param name="context"></param> /// <returns></returns> private Expression <Func <JsonToken, JsonToken> > ParseScalarLambda( FilterParser.ScalarFunctionContext context) { if (context.STARTS_WITH() != null) { return(s => VariantValue.FromObject( ((string)(VariantValue)s).StartsWith(ParseStringValue(context.STRING_LITERAL()), StringComparison.Ordinal))); } if (context.ENDS_WITH() != null) { return(s => VariantValue.FromObject( ((string)(VariantValue)s).EndsWith(ParseStringValue(context.STRING_LITERAL()), StringComparison.Ordinal))); } throw new ArgumentException("Bad function"); }
public async Task NodeWriteStaticScalarDateTimeValueVariableTestAsync() { var browser = _services(); var node = "http://test.org/UA/Data/#i=10228"; VariantValue expected = DateTime.UtcNow + TimeSpan.FromDays(11); // Act var result = await browser.NodeValueWriteAsync(_endpoint, new ValueWriteRequestModel { NodeId = node, Value = expected, DataType = "DateTime" }); // Assert await AssertResultAsync(node, expected, result); }
/// <summary> /// Called to read setting /// </summary> /// <param name="property"></param> /// <param name="value"></param> /// <returns></returns> public bool Get(string property, out VariantValue value) { Exception e = null; foreach (var invoker in _invokers) { try { return(invoker.Value.Get(property, out value)); } catch (Exception ex) { // Save last error, and continue _logger.Debug(ex, "Retrieving '{property}' failed!", property); e = ex; } } _logger.Error(e, "Exception during getter invocation."); throw e; }
private void LoadVariantValueDetail() { txtVariantValue.Focus(); if (IsEditModeValue()) { var objVariantValue = new VariantValue() { VariantValueId = lblVariantValueId.zToInt(), }.SelectList <VariantValue>()[0]; txtVariantValue.Text = objVariantValue.Value; lblVariantValueNote.Visible = false; } else { txtVariantValue.Text = string.Empty; lblVariantValueNote.Visible = true; } }
/// <inheritdoc/> public async Task ReportAsync(string propertyId, VariantValue value) { try { await _lock.WaitAsync(); if (Client != null) { var collection = new TwinCollection { [propertyId] = value?.ConvertTo <object>() }; await Client.UpdateReportedPropertiesAsync(collection); _reported.Remove(propertyId); _reported.Add(propertyId, value); } } finally { _lock.Release(); } }
public void CantAssignStringToIntegerValue() { int input = 123; var value = new VariantValue(input); Assert.IsFalse(value.IsValidValue("test")); bool assigned = false; try { value.Value = "test"; assigned = true; } catch (Exception e) { Console.WriteLine("Expected exception: {0}", e.Message); } Assert.IsFalse(assigned, "Exception expected"); }
/// <summary> /// Called when a service is invoked /// </summary> /// <param name="property"></param> /// <param name="value"></param> /// <returns></returns> public Controller Set(string property, VariantValue value) { try { var cast = value.ConvertTo(_property.PropertyType); if (_indexed) { _property.SetValue(_controller.Target, cast, new object[] { property }); } else { _property.SetValue(_controller.Target, cast); } return(_controller); } catch (Exception e) { _logger.Warning(e, "Exception during setter {controller} {name} invocation", _controller.Target.GetType().Name, _property.Name); throw; } }
/// <inheritdoc/> protected override bool TryEqualsVariant(VariantValue v, out bool equality) { if (v is MessagePackVariantValue packed) { equality = DeepEquals(_value, packed._value); return(true); } // Special comparison to timespan var type = GetValueType(); if (v.IsTimeSpan) { if (IsInteger || IsDecimal) { equality = v.Equals((VariantValue)TimeSpan.FromTicks( Convert.ToInt64(_value))); return(true); } } return(base.TryEqualsVariant(v, out equality)); }
/// <summary> /// Consolidated /// </summary> /// <param name="model"></param> /// <returns></returns> public static Dictionary <string, VariantValue> GetConsolidatedProperties( this DeviceTwinModel model) { var desired = model.Properties?.Desired; var reported = model.Properties?.Reported; if (reported == null || desired == null) { return((reported ?? desired) ?? new Dictionary <string, VariantValue>()); } var properties = new Dictionary <string, VariantValue>(desired); // Merge with reported foreach (var prop in reported) { if (properties.TryGetValue(prop.Key, out var existing)) { if (VariantValueEx.IsNull(existing) || VariantValueEx.IsNull(prop.Value)) { if (VariantValueEx.IsNull(existing) && VariantValueEx.IsNull(prop.Value)) { continue; } } else if (VariantValue.DeepEquals(existing, prop.Value)) { continue; } properties[prop.Key] = prop.Value; } else { properties.Add(prop.Key, prop.Value); } } return(properties); }
/// <summary> /// Process default settings /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="processed"></param> /// <returns></returns> private bool ProcessEdgeHostSettings(string key, VariantValue value, IDictionary <string, VariantValue> processed = null) { switch (key.ToLowerInvariant()) { case TwinProperty.Version: case TwinProperty.Type: break; case TwinProperty.SiteId: SiteId = (string)value; break; default: return(false); } if (processed != null) { processed[key] = value; } return(true); }
public async Task TestPublishTelemetryEventAndReceiveAsync(VariantValue v) { var bus = _factory.Resolve <ISubscriberMessageProcessor>(); var client = _factory.Resolve <IPublisherServiceEvents>(); var endpointId = "testid"; var result = new TaskCompletionSource <MonitoredItemMessageApiModel>(); await using (await client.NodePublishSubscribeByEndpointAsync(endpointId, ev => { result.SetResult(ev); return(Task.CompletedTask); })) { var expected = new MonitoredItemMessageModel { DataSetWriterId = "testid", EndpointId = endpointId, DisplayName = "holla", NodeId = "nodeid", SourceTimestamp = DateTime.UtcNow, Timestamp = DateTime.UtcNow, Value = v }; await bus.HandleSampleAsync(expected); await Task.WhenAny(result.Task, Task.Delay(5000)); Assert.True(result.Task.IsCompleted); var received = result.Task.Result; Assert.Equal(expected.DisplayName, received.DisplayName); Assert.Equal(expected.DataSetWriterId, received.DataSetWriterId); Assert.Equal(expected.NodeId, received.NodeId); Assert.Equal(expected.SourceTimestamp, received.SourceTimestamp); Assert.Equal(expected.Timestamp, received.Timestamp); Assert.NotNull(received?.Value); Assert.Equal(expected.Value, received.Value); } }
public void IntCompareTests() { VariantValue i1 = 1; VariantValue i2 = 2; VariantValue i3 = 2; Assert.True(i1 < i2); Assert.True(i1 <= i2); Assert.True(i2 > i1); Assert.True(i2 >= i1); Assert.True(i2 < 3); Assert.True(i2 <= 3); Assert.True(i2 <= 2); Assert.True(i2 <= i3); Assert.True(i2 >= 2); Assert.True(i2 >= i3); Assert.True(i2 != i1); Assert.True(i1 == 1); Assert.True(i2 == i3); Assert.True(i1 != 2); Assert.False(i2 == i1); Assert.False(i1 == 2); }
public void TimeSpanCompareTests() { VariantValue i1 = TimeSpan.FromSeconds(1); VariantValue i2 = TimeSpan.FromSeconds(2); VariantValue i3 = TimeSpan.FromSeconds(2); Assert.True(i1 < i2); Assert.True(i1 <= i2); Assert.True(i2 > i1); Assert.True(i2 >= i1); Assert.True(i2 < TimeSpan.FromSeconds(3)); Assert.True(i2 <= TimeSpan.FromSeconds(3)); Assert.True(i2 <= TimeSpan.FromSeconds(2)); Assert.True(i2 <= i3); Assert.True(i2 >= TimeSpan.FromSeconds(2)); Assert.True(i2 >= i3); Assert.True(i2 != i1); Assert.True(i1 == TimeSpan.FromSeconds(1)); Assert.True(i2 == i3); Assert.True(i1 != TimeSpan.FromSeconds(2)); Assert.False(i2 == i1); Assert.False(i1 == TimeSpan.FromSeconds(2)); }
public void NullCompareTests() { VariantValue i1 = null; VariantValue i2 = null; VariantValue i3 = "test"; VariantValue i4 = 0; VariantValue i5 = TimeSpan.FromSeconds(1); Assert.True(i1 is null); Assert.True(i1 == null); Assert.True(null == i1); Assert.True(i1 == i2); Assert.True(i1 != i3); Assert.True(i3 != i1); Assert.True(i1 != i4); Assert.True(i4 != i1); Assert.True(i4 != null); Assert.False(i4 == null); Assert.True(i3 != null); Assert.False(i3 == null); Assert.True(i5 != null); Assert.False(i5 == null); }
public void UlongCompareTests() { VariantValue i1 = 1ul; VariantValue i2 = 2ul; VariantValue i3 = 2ul; Assert.True(i1 < i2); Assert.True(i2 > i1); Assert.True(i2 < 3); Assert.True(i2 <= 2); Assert.True(i2 <= i3); Assert.True(i2 >= 2); Assert.True(i2 >= i3); Assert.True(i2 != i1); Assert.True(i1 == 1); Assert.True(i1 >= 1); Assert.True(i1 <= 1); Assert.True(i2 == i3); Assert.True(i1 != 2); Assert.True(i1 <= 2); Assert.False(i2 == i1); Assert.False(i1 == 2); }
private object GetFromVariantValue(ColumnInfo info, VariantValue value) { if (info.Nullable && value.IsNull) { return(null); } return(info.Type switch { ScalarType.Int32 => (object)value.Int32Value, ScalarType.Int16 => value.Int16Value, ScalarType.Int8 => value.Int8Value, ScalarType.Double => value.DoubleValue, ScalarType.Decimal => value.DecimalValue, ScalarType.Int64 => value.Int64Value, ScalarType.Bool => value.BoolValue, ScalarType.String => value.StringValue, ScalarType.Bytes => value.BytesValue.ToByteArray(), ScalarType.DateTime => DateTimeOffset.FromUnixTimeSeconds(value.DateTimeValue).UtcDateTime, ScalarType.DateTimeOffset => DateTimeOffset.FromUnixTimeMilliseconds(value.DateTimeOffsetValue), ScalarType.TimeSpan => new TimeSpan(value.TimeSpanValue), _ => null });
public async Task NodeWriteStaticScalarBooleanValueVariableWithBrowsePathTest3Async() { var browser = _services(); var path = new[] { "Objects", "http://test.org/UA/Data/#Data", "http://test.org/UA/Data/#Static", "http://test.org/UA/Data/#Scalar", "http://test.org/UA/Data/#BooleanValue" }; VariantValue expected = false; // Act var result = await browser.NodeValueWriteAsync(_endpoint, new ValueWriteRequestModel { BrowsePath = path, Value = expected, DataType = "Boolean" }); // Assert await AssertResultAsync("http://test.org/UA/Data/#i=10216", expected, result); expected = true; // Act result = await browser.NodeValueWriteAsync(_endpoint, new ValueWriteRequestModel { BrowsePath = path, Value = expected, DataType = "Boolean" }); // Assert await AssertResultAsync("http://test.org/UA/Data/#i=10216", expected, result); }
/// <summary> /// Helper to get values from object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="t"></param> /// <param name="key"></param> /// <param name="defaultValue"></param> /// <param name="compare"></param> /// <returns></returns> public static T?GetValueOrDefault <T>(this VariantValue t, string key, Func <T?> defaultValue, StringComparison compare = StringComparison.Ordinal) where T : struct { if (t.IsObject && t.TryGetProperty(key, out var value, compare) && !(value is null)) { try { // Handle enumerations serialized as string if (typeof(T).IsEnum && value.IsString && Enum.TryParse <T>((string)value, out var result)) { return(result); } return(value.ConvertTo <T>()); } catch { return(defaultValue()); } } return(defaultValue()); }
/// <summary> /// Compare operands /// </summary> /// <param name="model"></param> /// <param name="other"></param> /// <returns></returns> public static bool IsSameAs(this FilterOperandModel model, FilterOperandModel other) { if (model == null && other == null) { return(true); } if (model == null || other == null) { return(false); } if (model.AttributeId != other.AttributeId) { return(false); } if (model.Index != other.Index) { return(false); } if (!VariantValue.DeepEquals(model.Value, other.Value)) { return(false); } if (!model.BrowsePath.SequenceEqualsSafe(other.BrowsePath)) { return(false); } if (model.IndexRange != other.IndexRange) { return(false); } if (model.NodeId != other.NodeId) { return(false); } return(true); }
/// <summary> /// Equality comparison /// </summary> /// <param name="model"></param> /// <param name="that"></param> /// <returns></returns> public static bool IsSameAs(this AuthenticationMethodModel model, AuthenticationMethodModel that) { if (model == that) { return(true); } if (model == null || that == null) { return(false); } if (model.Configuration != null && that.Configuration != null) { if (!VariantValue.DeepEquals(model.Configuration, that.Configuration)) { return(false); } } return (model.Id == that.Id && model.SecurityPolicy == that.SecurityPolicy && (that.CredentialType ?? CredentialType.None) == (model.CredentialType ?? CredentialType.None)); }
/// <summary> /// Convert to results /// </summary> /// <param name="codec"></param> /// <param name="result"></param> /// <returns></returns> public static HistoricValueModel[] DecodeValues(this IVariantEncoder codec, VariantValue result) { var extensionObject = codec.DecodeExtensionObject(result); if (extensionObject?.Body is HistoryData data) { var results = data.DataValues.Select(d => new HistoricValueModel { ServerPicoseconds = d.ServerPicoseconds.ToNullable((ushort)0), SourcePicoseconds = d.SourcePicoseconds.ToNullable((ushort)0), ServerTimestamp = d.ServerTimestamp.ToNullable(DateTime.MinValue), SourceTimestamp = d.SourceTimestamp.ToNullable(DateTime.MinValue), StatusCode = d.StatusCode.ToNullable(StatusCodes.Good)?.CodeBits, Value = d.WrappedValue == Variant.Null ? null : codec.Encode(d.WrappedValue) }).ToArray(); if (extensionObject?.Body is HistoryModifiedData modified) { if (modified.ModificationInfos.Count != data.DataValues.Count) { throw new FormatException("Modification infos and data value count is not the same"); } for (var i = 0; i < modified.ModificationInfos.Count; i++) { results[i].ModificationInfo = new ModificationInfoModel { ModificationTime = modified.ModificationInfos[i].ModificationTime.ToNullable(DateTime.MinValue), UpdateType = (HistoryUpdateOperation)modified.ModificationInfos[i].UpdateType, UserName = modified.ModificationInfos[i].UserName }; } } return(results); } return(null); }
/// <summary> /// Equality comparison /// </summary> /// <param name="model"></param> /// <param name="that"></param> /// <returns></returns> public static bool IsSameAs(this ConnectionModel model, ConnectionModel that) { if (model == that) { return(true); } if (model == null || that == null) { return(false); } if (!that.Endpoint.IsSameAs(model.Endpoint)) { return(false); } if (that.Diagnostics?.AuditId != model.Diagnostics?.AuditId) { return(false); } if (!VariantValue.DeepEquals(that.User?.Value, model.User?.Value)) { return(false); } return(true); }
public void UlongAndIntGreaterThanTests() { VariantValue i1 = -1; VariantValue i2 = 2ul; VariantValue i3 = 2; Assert.True(i1 < i2); Assert.True(i2 > i1); Assert.True(i2 < 3); Assert.True(i2 <= 2); Assert.True(i2 >= 2); Assert.True(i2 <= i3); Assert.True(i2 >= i3); Assert.True(i2 != i1); Assert.True(i1 < 0); Assert.True(i1 <= 0); Assert.True(i1 == -1); Assert.True(i1 >= -1); Assert.True(i1 <= -1); Assert.True(i2 == i3); Assert.True(i1 != 2); Assert.False(i2 == i1); Assert.False(i1 == 2); }
/// <summary> /// Helper to get values from object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="t"></param> /// <param name="key"></param> /// <param name="compare"></param> /// <returns></returns> public static T GetValueOrDefault <T>(this VariantValue t, string key, StringComparison compare = StringComparison.Ordinal) { return(GetValueOrDefault(t, key, () => default(T), compare)); }
/// <summary> /// Adds the value to the XML element. /// </summary> private VariantValue CreateArray(XmlDocument document, Array array) { VariantValue variant = new VariantValue(); XmlElement parent = document.CreateElement( "ListOf" + GetXmlNameFromType(array.GetType().GetElementType()), Namespaces.OpcUaXsd); for (int ii = 0; ii < array.Length; ii++) { object element = array.GetValue(ii); VariantValue child = CreateScalar(document, element); if (child != null && child.Nodes != null) { for (int jj = 0; jj < child.Nodes.Length; jj++) { parent.AppendChild(child.Nodes[jj]); } } } variant.Nodes = new XmlNode[] { parent }; return variant; }
/// <summary> /// Adds the value to the XML element. /// </summary> private VariantValue CreateScalar(XmlDocument document, object value) { VariantValue variant = new VariantValue(); if (value == null) { return variant; } XmlElement element = null; switch (value.GetType().Name) { case "Boolean": { element = document.CreateElement("Boolean", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((bool)value); break; } case "Byte": { element = document.CreateElement("Byte", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((byte)value); break; } case "SByte": { element = document.CreateElement("SByte", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((sbyte)value); break; } case "Int16": { element = document.CreateElement("Int16", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((short)value); break; } case "UInt16": { element = document.CreateElement("UInt16", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((ushort)value); break; } case "Int32": { element = document.CreateElement("Int32", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((int)value); break; } case "UInt32": { element = document.CreateElement("UInt32", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((uint)value); break; } case "Int64": { element = document.CreateElement("Int64", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((long)value); break; } case "UInt64": { element = document.CreateElement("UInt64", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((ulong)value); break; } case "Single": { element = document.CreateElement("Float", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((float)value); break; } case "Double": { element = document.CreateElement("Double", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((double)value); break; } case "String": { element = document.CreateElement("String", Namespaces.OpcUaXsd); element.InnerText = (string)value; break; } case "DateTime": { element = document.CreateElement("DateTime", Namespaces.OpcUaXsd); element.InnerText = XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.Utc); break; } case "NodeId": { element = document.CreateElement("NodeId", Namespaces.OpcUaXsd); AddChild(document, element, "Identifier", ((NodeId)value).Identifier); break; } case "ExpandedNodeId": { element = document.CreateElement("ExpandedNodeId", Namespaces.OpcUaXsd); AddChild(document, element, "Identifier", ((ExpandedNodeId)value).Identifier); break; } case "QualifiedName": { element = document.CreateElement("QualifiedName", Namespaces.OpcUaXsd); AddChild(document, element, "NamespaceIndex", XmlConvert.ToString(((QualifiedName)value).NamespaceIndex)); AddChild(document, element, "Name", ((QualifiedName)value).Name); break; } case "LocalizedText": { element = document.CreateElement("LocalizedText", Namespaces.OpcUaXsd); AddChild(document, element, "Locale", ((LocalizedText)value).Locale); AddChild(document, element, "Text", ((LocalizedText)value).Text); break; } case "StatusCode": { element = document.CreateElement("StatusCode", Namespaces.OpcUaXsd); uint? code = ((StatusCode)value).Code; if (code != null && code.Value != StatusCodes.Good) { AddChild(document, element, "Code", XmlConvert.ToString(code.Value)); } break; } case "ExtensionObject": { element = document.CreateElement("ExtensionObject", Namespaces.OpcUaXsd); ExtensionObject extension = (ExtensionObject)value; if (extension != null) { XmlElement typeId = document.CreateElement("TypeId", Namespaces.OpcUaXsd); element.AppendChild(typeId); AddChild(document, typeId, "Identifier", extension.TypeId.Identifier); XmlElement body = document.CreateElement("Body", Namespaces.OpcUaXsd); if (extension.Body != null && extension.Body.Nodes != null && extension.Body.Nodes.Length > 0) { body.InnerXml = extension.Body.Nodes[0].OuterXml; } element.AppendChild(body); } break; } } variant.Nodes = new XmlNode[] { element }; return variant; }