public JTokenConverterConverter( IGremlinQueryFragmentDeserializer deserializer, IGremlinQueryEnvironment environment) { _deserializer = deserializer; _environment = environment; }
public override Traversal ToTraversal(IGremlinQueryEnvironment environment) { var keyProjectionTraversal = _keyProjection.ToTraversal(environment); var maybeValueProjectionTraversal = _valueProjection?.ToTraversal(environment); return((keyProjectionTraversal.Count == 0 && (maybeValueProjectionTraversal?.Count).GetValueOrDefault() == 0) ? Traversal.Empty : new LocalStep(Traversal .Create( 4, (keyProjectionTraversal, maybeValueProjectionTraversal), static (steps, state) => { var(keyProjectionTraversal, maybeValueProjectionTraversal) = state; steps[0] = UnfoldStep.Instance; steps[1] = GroupStep.Instance; steps[2] = new GroupStep.ByTraversalStep(Traversal .Create( keyProjectionTraversal.Count + 1, keyProjectionTraversal, static (steps, keyProjectionTraversal) => { steps[0] = new SelectColumnStep(Column.Keys); keyProjectionTraversal.Steps .AsSpan() .CopyTo(steps[1..]); }));
public IGremlinQueryEnvironment Transform(IGremlinQueryEnvironment environment) { return(environment .UseGremlinServer(builder => builder .Configure(_configuration) .Transform(_webSocketTransformations))); }
public static IGremlinQueryEnvironment EchoGraphsonString(this IGremlinQueryEnvironment environment) { return(environment .UseSerializer(GremlinQuerySerializer.Default) .UseExecutor(GremlinQueryExecutor.Identity) .UseDeserializer(GremlinQueryExecutionResultDeserializer.ToGraphsonString)); }
public static IGremlinQueryEnvironment EchoGroovyString(this IGremlinQueryEnvironment environment) { return(environment .ConfigureSerializer(serializer => serializer.ToGroovy()) .UseExecutor(GremlinQueryExecutor.Identity) .UseDeserializer(GremlinQueryExecutionResultDeserializer.ToString)); }
public IGremlinQueryEnvironment Transform(IGremlinQueryEnvironment environment) { return(environment .ConfigureOptions(options => { if (Enum.TryParse <QueryLogVerbosity>(_loggingSection["Verbosity"], out var verbosity)) { options = options.SetValue(WebSocketGremlinqOptions.QueryLogVerbosity, verbosity); } if (Enum.TryParse <LogLevel>(_loggingSection[$"{nameof(LogLevel)}"], out var logLevel)) { options = options.SetValue(WebSocketGremlinqOptions.QueryLogLogLevel, logLevel); } if (Enum.TryParse <Formatting>(_loggingSection[$"{nameof(Formatting)}"], out var formatting)) { options = options.SetValue(WebSocketGremlinqOptions.QueryLogFormatting, formatting); } if (Enum.TryParse <GroovyFormatting>(_loggingSection[$"{nameof(GroovyFormatting)}"], out var groovyFormatting)) { options = options.SetValue(WebSocketGremlinqOptions.QueryLogGroovyFormatting, groovyFormatting); } return options; })); }
public static IGremlinQueryEnvironment AddFakePartitionKey(this IGremlinQueryEnvironment env) { return(env .ConfigureAddStepHandler(stepHandler => stepHandler .Override <AddVStep>((steps, step, env, overridden, recurse) => overridden(steps, step, env, recurse) .Push(new PropertyStep("PartitionKey", "PartitionKey"))))); }
internal static Key GetKey(this IGremlinQueryEnvironment environment, Expression expression) { var memberExpression = expression.AssumeMemberExpression(); return(memberExpression.TryGetWellKnownMember() == WellKnownMember.PropertyValue && memberExpression.Expression is MemberExpression sourceMemberExpression ? environment.GetCache().GetKey(sourceMemberExpression.Member) : environment.GetCache().GetKey(memberExpression.Member)); }
public IAsyncEnumerable <TElement> Deserialize <TElement>(object result, IGremlinQueryEnvironment environment) { if (!typeof(TElement).IsAssignableFrom(typeof(string))) { throw new InvalidOperationException($"Can't deserialize a string to {typeof(TElement).Name}. Make sure you cast call Cast<string>() on the query before executing it."); } return(AsyncEnumerableEx.Return((TElement)(object)result?.ToString())); }
public static IGremlinQueryEnvironment UseCosmosDb(this IGremlinQueryEnvironment env, Func <ICosmosDbConfigurationBuilder, IGremlinQueryEnvironmentBuilder> transformation) { return(env .ConfigureFeatureSet(featureSet => featureSet .ConfigureGraphFeatures(_ => GraphFeatures.Transactions | GraphFeatures.Persistence | GraphFeatures.ConcurrentAccess) .ConfigureVariableFeatures(_ => VariableFeatures.BooleanValues | VariableFeatures.IntegerValues | VariableFeatures.ByteValues | VariableFeatures.DoubleValues | VariableFeatures.FloatValues | VariableFeatures.IntegerValues | VariableFeatures.LongValues | VariableFeatures.StringValues) .ConfigureVertexFeatures(_ => VertexFeatures.RemoveVertices | VertexFeatures.MetaProperties | VertexFeatures.AddVertices | VertexFeatures.MultiProperties | VertexFeatures.StringIds | VertexFeatures.UserSuppliedIds | VertexFeatures.AddProperty | VertexFeatures.RemoveProperty) .ConfigureVertexPropertyFeatures(_ => VertexPropertyFeatures.StringIds | VertexPropertyFeatures.UserSuppliedIds | VertexPropertyFeatures.RemoveProperty | VertexPropertyFeatures.BooleanValues | VertexPropertyFeatures.ByteValues | VertexPropertyFeatures.DoubleValues | VertexPropertyFeatures.FloatValues | VertexPropertyFeatures.IntegerValues | VertexPropertyFeatures.LongValues | VertexPropertyFeatures.StringValues) .ConfigureEdgeFeatures(_ => EdgeFeatures.AddEdges | EdgeFeatures.RemoveEdges | EdgeFeatures.StringIds | EdgeFeatures.UserSuppliedIds | EdgeFeatures.AddProperty | EdgeFeatures.RemoveProperty) .ConfigureEdgePropertyFeatures(_ => EdgePropertyFeatures.Properties | EdgePropertyFeatures.BooleanValues | EdgePropertyFeatures.ByteValues | EdgePropertyFeatures.DoubleValues | EdgePropertyFeatures.FloatValues | EdgePropertyFeatures.IntegerValues | EdgePropertyFeatures.LongValues | EdgePropertyFeatures.StringValues)) .ConfigureOptions(options => options .SetValue(GremlinqOption.VertexProjectionSteps, ImmutableList <Step> .Empty) .SetValue(GremlinqOption.EdgeProjectionSteps, ImmutableList <Step> .Empty)) .ConfigureSerializer(serializer => serializer .ConfigureFragmentSerializer(fragmentSerializer => fragmentSerializer .Override <CosmosDbKey>((key, env, overridden, recurse) => recurse.Serialize( key.PartitionKey != null ? new[] { key.PartitionKey, key.Id } : (object)key.Id, env)) .Override <HasKeyStep>((step, env, overridden, recurse) => { return step.Argument is P p && (!p.OperatorName.Equals("eq", StringComparison.OrdinalIgnoreCase)) ? recurse.Serialize(new WhereTraversalStep(new Step[] { KeyStep.Instance, new IsStep(p) }), env) : overridden(step, env, recurse); }) .Override <SkipStep>((step, env, overridden, recurse) => recurse.Serialize(new RangeStep(step.Count, -1, step.Scope), env)) .Override <LimitStep>((step, env, overridden, recurse) => { // Workaround for https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/33998623-cosmosdb-s-implementation-of-the-tinkerpop-dsl-has return step.Count <= int.MaxValue ? overridden(step, env, recurse) : throw new ArgumentOutOfRangeException(nameof(step), "CosmosDb doesn't currently support values for 'Limit' outside the range of a 32-bit-integer."); }) .Override <TailStep>((step, env, overridden, recurse) => { // Workaround for https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/33998623-cosmosdb-s-implementation-of-the-tinkerpop-dsl-has return step.Count <= int.MaxValue ? overridden(step, env, recurse) : throw new ArgumentOutOfRangeException(nameof(step), "CosmosDb doesn't currently support values for 'Tail' outside the range of a 32-bit-integer."); }) .Override <RangeStep>((step, env, overridden, recurse) => { // Workaround for https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/33998623-cosmosdb-s-implementation-of-the-tinkerpop-dsl-has return step.Lower <= int.MaxValue && step.Upper <= int.MaxValue ? overridden(step, env, recurse) : throw new ArgumentOutOfRangeException(nameof(step), "CosmosDb doesn't currently support values for 'Range' outside the range of a 32-bit-integer."); }) .Override <long>((l, env, overridden, recurse) => { // Workaround for https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/33998623-cosmosdb-s-implementation-of-the-tinkerpop-dsl-has return recurse.Serialize((int)l, env); })) .ToGroovy()) .ConfigureWebSocket(builder => transformation(new CosmosDbConfigurationBuilder(builder.SetSerializationFormat(SerializationFormat.GraphSonV2)))) .StoreTimeSpansAsNumbers()); }
public static IGremlinQueryEnvironment EchoGraphsonString(this IGremlinQueryEnvironment environment) { return(environment .UseSerializer(GremlinQuerySerializer.Default) .UseExecutor(GremlinQueryExecutor.Identity) .ConfigureDeserializer(_ => _ .ConfigureFragmentDeserializer(_ => _ .ToGraphsonString()))); }
public GraphsonJsonSerializer( DefaultValueHandling defaultValueHandling, IGremlinQueryEnvironment environment, IGremlinQueryFragmentDeserializer fragmentDeserializer) { DefaultValueHandling = defaultValueHandling; ContractResolver = new GremlinContractResolver(environment.Model.PropertiesModel); Converters.Add(new JTokenConverterConverter(fragmentDeserializer, environment)); }
public static IGremlinQueryEnvironment AddFakePartitionKey(this IGremlinQueryEnvironment env) { return(env .ConfigureSerializer(serializer => serializer .ConfigureFragmentSerializer(serializer => serializer .Override <AddVStep>((step, env, overridden, recurse) => new[] { overridden(step, env, recurse), recurse.Serialize(new PropertyStep.ByKeyStep("PartitionKey", "PartitionKey"), env) })))); }
public static IGremlinQueryEnvironment StoreTimeSpansAsNumbers(this IGremlinQueryEnvironment environment) { return(environment .ConfigureSerializer(serializer => serializer .ConfigureFragmentSerializer(fragmentSerializer => fragmentSerializer .Override <TimeSpan>((t, env, _, recurse) => recurse.Serialize(t.TotalMilliseconds, env)))) .ConfigureDeserializer(deserializer => deserializer .ConfigureFragmentDeserializer(fragmentDeserializer => fragmentDeserializer .Override <JValue>((jValue, type, env, overridden, recurse) => type == typeof(TimeSpan) ? TimeSpan.FromMilliseconds(jValue.Value <double>()) : overridden(jValue, type, env, recurse))))); }
protected GremlinQueryBase( IImmutableList <Step> steps, IGremlinQueryEnvironment environment, QuerySemantics semantics, IImmutableDictionary <StepLabel, QuerySemantics> stepLabelSemantics, bool surfaceVisible) { Steps = steps; Semantics = semantics; Environment = environment; SurfaceVisible = surfaceVisible; StepLabelSemantics = stepLabelSemantics; }
public static IGremlinQueryEnvironment UseJanusGraph(this IGremlinQueryEnvironment environment, Func <IWebSocketGremlinQueryEnvironmentBuilder, IWebSocketGremlinQueryEnvironmentBuilder> builderAction) { return(environment .UseGremlinServer(builderAction) .ConfigureFeatureSet(featureSet => featureSet .ConfigureGraphFeatures(_ => GraphFeatures.Computer | GraphFeatures.Transactions | GraphFeatures.ThreadedTransactions | GraphFeatures.Persistence) .ConfigureVariableFeatures(_ => VariableFeatures.MapValues) .ConfigureVertexFeatures(_ => VertexFeatures.AddVertices | VertexFeatures.RemoveVertices | VertexFeatures.MultiProperties | VertexFeatures.AddProperty | VertexFeatures.RemoveProperty | VertexFeatures.StringIds) .ConfigureVertexPropertyFeatures(_ => VertexPropertyFeatures.RemoveProperty | VertexPropertyFeatures.NumericIds | VertexPropertyFeatures.StringIds | VertexPropertyFeatures.Properties | VertexPropertyFeatures.BooleanValues | VertexPropertyFeatures.ByteValues | VertexPropertyFeatures.DoubleValues | VertexPropertyFeatures.FloatValues | VertexPropertyFeatures.IntegerValues | VertexPropertyFeatures.LongValues | VertexPropertyFeatures.StringValues) .ConfigureEdgeFeatures(_ => EdgeFeatures.AddEdges | EdgeFeatures.RemoveEdges | EdgeFeatures.AddProperty | EdgeFeatures.RemoveProperty | EdgeFeatures.NumericIds | EdgeFeatures.StringIds | EdgeFeatures.UuidIds | EdgeFeatures.CustomIds | EdgeFeatures.AnyIds) .ConfigureEdgePropertyFeatures(_ => EdgePropertyFeatures.Properties | EdgePropertyFeatures.BooleanValues | EdgePropertyFeatures.ByteValues | EdgePropertyFeatures.DoubleValues | EdgePropertyFeatures.FloatValues | EdgePropertyFeatures.IntegerValues | EdgePropertyFeatures.LongValues | EdgePropertyFeatures.StringValues)));; }
protected GremlinQueryBase( IImmutableStack <Step> steps, IGremlinQueryEnvironment environment, QuerySemantics semantics, IImmutableDictionary <StepLabel, QuerySemantics> stepLabelSemantics, QueryFlags flags) { Steps = steps; Semantics = semantics; Environment = environment; Flags = flags; StepLabelSemantics = stepLabelSemantics; }
public P?TryGetP(ExpressionSemantics semantics, object?value, IGremlinQueryEnvironment environment) { if (value is string { Length : > 0 } str&& semantics is StringExpressionSemantics { Comparison : StringComparison.OrdinalIgnoreCase } stringExpressionSemantics) { switch (_indexConfiguration) { case NeptuneElasticSearchIndexConfiguration.Standard : { if (!str.Any(c => char.IsWhiteSpace(c))) //Can't do better. Insight welcome. { switch (stringExpressionSemantics) { // This will only work for property values that don't contain e.g. whitespace // and would be tokenized as a complete string. As it is, a vertex property // with value "John Doe" would match a query "StartsWith('Doe') which is // not really what's expected. So we can't do better than a case-insensitive // "Contains(..)" case HasInfixExpressionSemantics : return(new P("eq", $"Neptune#fts *{value}*")); } } break; } case NeptuneElasticSearchIndexConfiguration.LowercaseKeyword: { str = str .Replace(" ", @"\ "); switch (stringExpressionSemantics) { case StartsWithExpressionSemantics: return(new P("eq", $"Neptune#fts {str}*")); case EndsWithExpressionSemantics: return(new P("eq", $"Neptune#fts *{str}")); case HasInfixExpressionSemantics: return(new P("eq", $"Neptune#fts *{str}*")); } break; } } } return(default);
public static IGremlinQueryEnvironment UseNeptune(this IGremlinQueryEnvironment environment, Func <IWebSocketGremlinQueryExecutorBuilder, IWebSocketGremlinQueryExecutorBuilder> transformation) { return(environment .UseWebSocket(transformation) .ConfigureSerializer(serializer => serializer .ConfigureFragmentSerializer(fragmentSerializer => fragmentSerializer .Override <PropertyStep>((step, env, overridden, recurse) => overridden(Cardinality.List.Equals(step.Cardinality) ? new PropertyStep(step.Key, step.Value, step.MetaProperties, Cardinality.Set) : step, env, recurse)))) .ConfigureFeatureSet(featureSet => featureSet .ConfigureGraphFeatures(_ => GraphFeatures.Transactions | GraphFeatures.Persistence | GraphFeatures.ConcurrentAccess) .ConfigureVariableFeatures(_ => VariableFeatures.None) .ConfigureVertexFeatures(_ => VertexFeatures.AddVertices | VertexFeatures.RemoveVertices | VertexFeatures.MultiProperties | VertexFeatures.UserSuppliedIds | VertexFeatures.AddProperty | VertexFeatures.RemoveProperty | VertexFeatures.StringIds) .ConfigureVertexPropertyFeatures(_ => VertexPropertyFeatures.RemoveProperty | VertexPropertyFeatures.NumericIds | VertexPropertyFeatures.StringIds | VertexPropertyFeatures.Properties | VertexPropertyFeatures.BooleanValues | VertexPropertyFeatures.ByteValues | VertexPropertyFeatures.DoubleValues | VertexPropertyFeatures.FloatValues | VertexPropertyFeatures.IntegerValues | VertexPropertyFeatures.LongValues | VertexPropertyFeatures.StringValues) .ConfigureEdgeFeatures(_ => EdgeFeatures.AddEdges | EdgeFeatures.RemoveEdges | EdgeFeatures.UserSuppliedIds | EdgeFeatures.AddProperty | EdgeFeatures.RemoveProperty | EdgeFeatures.NumericIds | EdgeFeatures.StringIds | EdgeFeatures.UuidIds | EdgeFeatures.CustomIds | EdgeFeatures.AnyIds) .ConfigureEdgePropertyFeatures(_ => EdgePropertyFeatures.Properties | EdgePropertyFeatures.BooleanValues | EdgePropertyFeatures.ByteValues | EdgePropertyFeatures.DoubleValues | EdgePropertyFeatures.FloatValues | EdgePropertyFeatures.IntegerValues | EdgePropertyFeatures.LongValues | EdgePropertyFeatures.StringValues))); }
public IGremlinQueryEnvironment Transform(IGremlinQueryEnvironment environment) { return(environment .UseCosmosDb(builder => { return builder .At( _configuration.GetRequiredConfiguration("Uri"), _configuration.GetRequiredConfiguration("Database"), _configuration.GetRequiredConfiguration("Graph")) .AuthenticateBy(_configuration.GetRequiredConfiguration("AuthKey")) .ConfigureWebSocket(webSocketBuilder => webSocketBuilder .Configure(_configuration)); })); }
public GraphsonJsonSerializer(IGremlinQueryEnvironment environment, params JsonConverter[] additionalConverters) { foreach (var additionalConverter in additionalConverters) { Converters.Add(additionalConverter); } Converters.Add(new FlatteningConverter()); Converters.Add(new TimespanConverter()); Converters.Add(new DateTimeOffsetConverter()); Converters.Add(new DateTimeConverter()); Converters.Add(new ElementConverter(environment.Model)); ContractResolver = new GremlinContractResolver(environment.Model.PropertiesModel); DefaultValueHandling = DefaultValueHandling.Populate; }
internal static Key GetKey(this IGremlinQueryEnvironment environment, Expression expression) { if (expression is LambdaExpression lambdaExpression) { return(environment.GetKey(lambdaExpression.Body)); } if (expression.Strip() is MemberExpression memberExpression) { return(memberExpression.TryGetWellKnownMember() == WellKnownMember.PropertyValue && memberExpression.Expression is MemberExpression sourceMemberExpression ? environment.GetCache().GetKey(sourceMemberExpression.Member) : environment.GetCache().GetKey(memberExpression.Member)); } throw new ExpressionNotSupportedException(expression); }
public override Traversal ToTraversal(IGremlinQueryEnvironment environment) { var inner = _inner.ToTraversal(environment); if (inner.Count > 0) { return(new LocalStep(Traversal.Create( inner.Count + 2, inner, static (steps, inner) => { steps[0] = UnfoldStep.Instance; steps[^ 1] = FoldStep.Instance; inner .Steps .AsSpan() .CopyTo(steps[1..]);
public static IGremlinQueryEnvironment UseJanusGraph(this IGremlinQueryEnvironment environment, Func <IWebSocketGremlinQueryExecutorBuilder, IWebSocketGremlinQueryExecutorBuilder> builderAction) { return(environment .UseGremlinServer(builderAction) .ConfigureFeatureSet(featureSet => featureSet .ConfigureGraphFeatures(_ => GraphFeatures.Computer | GraphFeatures.Transactions | GraphFeatures.ThreadedTransactions | GraphFeatures.Persistence) .ConfigureVariableFeatures(_ => VariableFeatures.MapValues) .ConfigureVertexFeatures(_ => VertexFeatures.AddVertices | VertexFeatures.RemoveVertices | VertexFeatures.MultiProperties | VertexFeatures.AddProperty | VertexFeatures.RemoveProperty | VertexFeatures.StringIds) .ConfigureVertexPropertyFeatures(_ => VertexPropertyFeatures.RemoveProperty | VertexPropertyFeatures.NumericIds | VertexPropertyFeatures.StringIds | VertexPropertyFeatures.Properties | VertexPropertyFeatures.BooleanValues | VertexPropertyFeatures.ByteValues | VertexPropertyFeatures.DoubleValues | VertexPropertyFeatures.FloatValues | VertexPropertyFeatures.IntegerValues | VertexPropertyFeatures.LongValues | VertexPropertyFeatures.StringValues) .ConfigureEdgeFeatures(_ => EdgeFeatures.AddEdges | EdgeFeatures.RemoveEdges | EdgeFeatures.AddProperty | EdgeFeatures.RemoveProperty | EdgeFeatures.NumericIds | EdgeFeatures.StringIds | EdgeFeatures.UuidIds | EdgeFeatures.CustomIds | EdgeFeatures.AnyIds) .ConfigureEdgePropertyFeatures(_ => EdgePropertyFeatures.Properties | EdgePropertyFeatures.BooleanValues | EdgePropertyFeatures.ByteValues | EdgePropertyFeatures.DoubleValues | EdgePropertyFeatures.FloatValues | EdgePropertyFeatures.IntegerValues | EdgePropertyFeatures.LongValues | EdgePropertyFeatures.StringValues)) .ConfigureModel(model => model .ConfigureNativeTypes(types => types .Remove(typeof(byte[])))) .ConfigureSerializer(_ => _ .ConfigureFragmentSerializer(_ => _ .Override <byte[]>((bytes, env, overridden, recurse) => recurse.Serialize(Convert.ToBase64String(bytes), env))))); }
public static IGremlinQueryEnvironment UseGremlinServer(this IGremlinQueryEnvironment environment, Func <IWebSocketGremlinQueryExecutorBuilder, IWebSocketGremlinQueryExecutorBuilder> builderAction) { return(environment .UseWebSocket(builderAction) .ConfigureFeatureSet(featureSet => featureSet .ConfigureGraphFeatures(graphFeatures => graphFeatures & ~(GraphFeatures.Transactions | GraphFeatures.ThreadedTransactions | GraphFeatures.ConcurrentAccess)) .ConfigureVertexFeatures(vertexFeatures => vertexFeatures & ~(VertexFeatures.Upsert | VertexFeatures.CustomIds)) .ConfigureVertexPropertyFeatures(vPropertiesFeatures => vPropertiesFeatures & ~(VertexPropertyFeatures.CustomIds)) .ConfigureEdgeFeatures(edgeProperties => edgeProperties & ~(EdgeFeatures.Upsert | EdgeFeatures.CustomIds))) .ConfigureSerializer(s => s .ConfigureFragmentSerializer(fragmentSerializer => fragmentSerializer .Override <IGremlinQueryBase>((query, env, overridden, recurse) => { if (env.Options.GetValue(GremlinServerGremlinqOptions.WorkaroundTinkerpop2112)) { query = query.AsAdmin().ConfigureSteps <IGremlinQueryBase>(steps => ImmutableStack.Create(steps.Reverse().WorkaroundTINKERPOP_2112().ToArray())); } return overridden(query, env, recurse); })))); }
public IGremlinQueryEnvironment Transform(IGremlinQueryEnvironment environment) { return(_environmentTransformation(environment)); }
public IGremlinQueryEnvironment Transform(IGremlinQueryEnvironment environment) { return(environment.UseModel(_model)); }
public static IGremlinQueryEnvironment UseExecutor(this IGremlinQueryEnvironment environment, IGremlinQueryExecutor executor) => environment.ConfigureExecutor(_ => executor);
public static IGremlinQueryEnvironment UseDeserializer(this IGremlinQueryEnvironment environment, IGremlinQueryExecutionResultDeserializer deserializer) => environment.ConfigureDeserializer(_ => deserializer);
public static IGremlinQueryEnvironment UseSerializer(this IGremlinQueryEnvironment environment, IGremlinQuerySerializer serializer) => environment.ConfigureSerializer(_ => serializer);