This is an automated email from the ASF dual-hosted git repository.

xiazcy pushed a commit to branch asbool-step
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 8de45e454d532ace1508aa68d9fa794b83e49d10
Author: Alexey Temnikov <[email protected]>
AuthorDate: Fri Jun 6 23:08:01 2025 -0700

    asbool step initial implementation
---
 CHANGELOG.asciidoc                                 |  1 +
 docs/src/dev/provider/gremlin-semantics.asciidoc   | 25 +++++++++
 docs/src/reference/the-traversal.asciidoc          | 20 +++++++
 .../grammar/DefaultGremlinBaseVisitor.java         | 14 +++--
 .../language/grammar/TraversalMethodVisitor.java   |  8 +++
 .../traversal/dsl/graph/GraphTraversal.java        | 13 +++++
 .../gremlin/process/traversal/dsl/graph/__.java    |  7 +++
 .../process/traversal/step/map/AsBoolStep.java     | 60 ++++++++++++++++++++
 .../process/traversal/step/map/AsBoolStepTest.java | 53 ++++++++++++++++++
 .../Process/Traversal/GraphTraversal.cs            |  9 +++
 .../src/Gremlin.Net/Process/Traversal/__.cs        |  8 +++
 .../Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs | 14 +++--
 gremlin-go/driver/anonymousTraversal.go            |  7 ++-
 gremlin-go/driver/cucumber/gremlin.go              |  8 ++-
 gremlin-go/driver/graphTraversal.go                | 10 +++-
 .../lib/process/graph-traversal.js                 | 11 ++++
 .../gremlin-javascript/test/cucumber/gremlin.js    |  8 ++-
 gremlin-language/src/main/antlr4/Gremlin.g4        |  6 ++
 .../gremlin_python/process/graph_traversal.py      | 12 ++++
 gremlin-python/src/main/python/radish/gremlin.py   |  8 ++-
 .../gremlin/test/features/map/AsBool.feature       | 65 ++++++++++++++++++++++
 21 files changed, 348 insertions(+), 19 deletions(-)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 30aa4d1d6c..8699e308d5 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -69,6 +69,7 @@ This release also includes changes from <<release-3-7-XXX, 
3.7.XXX>>.
 * Added and made `OffsetDateTime` serializers the default for existing date 
types in Python, Go, JavaScript, and .NET. `Date` is only used to deserialize 
from server.
 * Added missing strategies in `gremlin-go`, updated certain strategies to take 
varargs and updated `GoTranslatorVisitor` for corresponding translations.
 * Fixed `BigInt` and `BigDecimal` parsing in `gremlin-go` cucumber test suite, 
fixed `UnscaledValue` type in `BigDecimal` struct and added `ParseBigDecimal` 
method.
+* Added boolean parsing step `asBool()`.
 * Added validation to `valueMap()`, `propertyMap()`, `groupCount()`, `sack()`, 
`dedup()`, `sample()`, and `aggregate()` to prevent the invalid usage of 
multiple `by()` modulators.
 * Deprecated `ProcessLimitedStandardSuite` and `ProcessLimitedComputerSuite` 
in favor of `ProcessEmbeddedStandardSuite` and `ProcessEmbeddedComputerSuite` 
respectively.
 * Deprecated `ProcessStandardSuite` and the `ProcessComputerSuite` in favor of 
Gherkin testing and the `ProcessEmbeddedStandardSuite` and 
`ProcessEmbeddedComputerSuite` for testing JVM-specific Gremlin behaviors.
diff --git a/docs/src/dev/provider/gremlin-semantics.asciidoc 
b/docs/src/dev/provider/gremlin-semantics.asciidoc
index a499a015fe..5966360fb5 100644
--- a/docs/src/dev/provider/gremlin-semantics.asciidoc
+++ b/docs/src/dev/provider/gremlin-semantics.asciidoc
@@ -801,6 +801,31 @@ Incoming date remains unchanged.
 See: 
link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsDateStep.java[source],
 link:https://tinkerpop.apache.org/docs/x.y.z/reference/#asDate-step[reference]
 
+[[asBool-step]]
+=== asBool()
+
+*Description:* Parse the value of the incoming traverser as boolean.
+
+*Syntax:* `asBool()`
+
+[width="100%",options="header"]
+|=========================================================
+|Start Step |Mid Step |Modulated |Domain |Range
+|N |Y |N |`any` |`any`
+|=========================================================
+
+*Arguments:*
+
+None
+
+`null` values return `false`, numbers evaluate to `true` if non-zero and 
strings only accept "true" or "false".
+
+*Exceptions*
+* If the incoming traverser type is unsupported or a string other than "true" 
or "false" then an `IllegalArgumentException` is thrown.
+
+See: 
link:https://github.com/apache/tinkerpop/tree/x.y.z/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStep.java[source],
+link:https://tinkerpop.apache.org/docs/x.y.z/reference/#asBool-step[reference]
+
 [[barrier-step]]
 === barrier()
 
diff --git a/docs/src/reference/the-traversal.asciidoc 
b/docs/src/reference/the-traversal.asciidoc
index eaf36d2b96..f27adaea14 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -829,6 +829,26 @@ g.inject(datetime("2023-08-24T00:00:00Z")).asDate() <3>
 
 
link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#asDate()++[`asDate()`]
 
+[[asBool-step]]
+=== AsBool Step
+
+The `asBool()`-step (*map*) converts the incoming traverser to a boolean 
value. Numbers evaluate to
+`true` when non-zero (and not `NaN`), `null` evaluates to `false` and strings 
are only accepted when
+equal to `"true"` or `"false"` (case-insensitive). All other types will throw 
an `IllegalArgumentException`.
+
+[gremlin-groovy,modern]
+----
+g.inject(1).asBool() <1>
+g.inject("false").asBool() <2>
+----
+
+<1> Convert number to boolean
+<2> Convert string to boolean
+
+*Additional References*
+
+link:++https://tinkerpop.apache.org/javadocs/x.y.z/core/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.html#asBool()++[`asBool()`]
+
 [[barrier-step]]
 === Barrier Step
 
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
index 37752152ff..09d1b97a4f 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/DefaultGremlinBaseVisitor.java
@@ -1050,11 +1050,15 @@ public class DefaultGremlinBaseVisitor<T> extends 
AbstractParseTreeVisitor<T> im
        /**
         * {@inheritDoc}
         */
-       @Override public T visitTraversalMethod_substring_Scope_int_int(final 
GremlinParser.TraversalMethod_substring_Scope_int_intContext ctx) { 
notImplemented(ctx); return null; }
-       /**
-        * {@inheritDoc}
-        */
-       @Override public T visitTraversalMethod_asDate(final 
GremlinParser.TraversalMethod_asDateContext ctx) { notImplemented(ctx); return 
null; }
+        @Override public T visitTraversalMethod_substring_Scope_int_int(final 
GremlinParser.TraversalMethod_substring_Scope_int_intContext ctx) { 
notImplemented(ctx); return null; }
+        /**
+         * {@inheritDoc}
+         */
+        @Override public T visitTraversalMethod_asBool(final 
GremlinParser.TraversalMethod_asBoolContext ctx) { notImplemented(ctx); return 
null; }
+        /**
+         * {@inheritDoc}
+         */
+        @Override public T visitTraversalMethod_asDate(final 
GremlinParser.TraversalMethod_asDateContext ctx) { notImplemented(ctx); return 
null; }
        /**
         * {@inheritDoc}
         */
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
index 872e0eb6e8..6b1578fb1e 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/language/grammar/TraversalMethodVisitor.java
@@ -2068,6 +2068,14 @@ public class TraversalMethodVisitor extends 
TraversalRootVisitor<GraphTraversal>
                 
antlr.genericVisitor.parseIntegral(ctx.integerLiteral(1)).intValue());
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public GraphTraversal visitTraversalMethod_asBool(final 
GremlinParser.TraversalMethod_asBoolContext ctx) {
+        return graphTraversal.asBool();
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
index 041888cb22..4e70acb716 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/GraphTraversal.java
@@ -83,6 +83,7 @@ import 
org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsDateStep;
+import org.apache.tinkerpop.gremlin.process.traversal.step.map.AsBoolStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.step.map.AsStringGlobalStep;
 import 
org.apache.tinkerpop.gremlin.process.traversal.step.map.AsStringLocalStep;
 import org.apache.tinkerpop.gremlin.process.traversal.step.map.CallStep;
@@ -1852,6 +1853,17 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
         return this.asAdmin().addStep(new FormatStep<>(this.asAdmin(), 
format));
     }
 
+    /**
+     * Parse the incoming traverser as a boolean value.
+     *
+     * @return the traversal with an appended {@link AsBoolStep}.
+     * @see <a 
href="http://tinkerpop.apache.org/docs/${project.version}/reference/#asBool-step";
 target="_blank">Reference Documentation - asBool Step</a>
+     */
+    public default GraphTraversal<S, Boolean> asBool() {
+        this.asAdmin().getBytecode().addStep(Symbols.asBool);
+        return this.asAdmin().addStep(new AsBoolStep<>(this.asAdmin()));
+    }
+
     /**
      * Parse value of the incoming traverser as an ISO-8601 {@link 
OffsetDateTime}.
      *
@@ -4131,6 +4143,7 @@ public interface GraphTraversal<S, E> extends 
Traversal<S, E> {
         public static final String substring = "substring";
         public static final String split = "split";
         public static final String format = "format";
+        public static final String asBool = "asBool";
         public static final String asDate = "asDate";
         public static final String dateAdd = "dateAdd";
         public static final String dateDiff = "dateDiff";
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
index e1edcfc5f4..22bb3b1be0 100644
--- 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/dsl/graph/__.java
@@ -772,6 +772,13 @@ public class __ {
         return __.<A>start().format(format);
     }
 
+    /**
+     * @see GraphTraversal#asBool()
+     */
+    public static <A> GraphTraversal<A, Boolean> asBool() {
+        return __.<A>start().asBool();
+    }
+
     /**
      * @see GraphTraversal#asDate()
      */
diff --git 
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStep.java
 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStep.java
new file mode 100644
index 0000000000..299fc6c993
--- /dev/null
+++ 
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStep.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.Traverser;
+import 
org.apache.tinkerpop.gremlin.process.traversal.traverser.TraverserRequirement;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * Reference implementation for boolean parsing step.
+ */
+public final class AsBoolStep<S> extends ScalarMapStep<S, Boolean> {
+
+    public AsBoolStep(final Traversal.Admin traversal) {
+        super(traversal);
+    }
+
+    @Override
+    protected Boolean map(final Traverser.Admin<S> traverser) {
+        final Object object = traverser.get();
+        if (object == null) return false;
+        if (object instanceof Boolean) return (Boolean) object;
+        if (object instanceof Number) {
+            final double d = ((Number) object).doubleValue();
+            return !Double.isNaN(d) && d != 0d;
+        }
+        if (object instanceof String) {
+            final String str = (String) object;
+            if (str.equalsIgnoreCase("true")) return true;
+            if (str.equalsIgnoreCase("false")) return false;
+            throw new IllegalArgumentException("Can't parse " + object + " as 
Boolean.");
+        }
+        throw new IllegalArgumentException("Can't parse " + 
object.getClass().getName() + " as Boolean.");
+    }
+
+    @Override
+    public Set<TraverserRequirement> getRequirements() {
+        return Collections.singleton(TraverserRequirement.OBJECT);
+    }
+
+}
diff --git 
a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStepTest.java
 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStepTest.java
new file mode 100644
index 0000000000..a09dfdc199
--- /dev/null
+++ 
b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/map/AsBoolStepTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.process.traversal.step.map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.step.StepTest;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class AsBoolStepTest extends StepTest {
+
+    @Override
+    protected List<Traversal> getTraversals() {
+        return Collections.singletonList(__.asBool());
+    }
+
+    @Test
+    public void shouldParseBoolean() {
+        assertEquals(true, __.__(1).asBool().next());
+        assertEquals(false, __.__(0).asBool().next());
+        assertEquals(true, __.__(3.14).asBool().next());
+        assertEquals(false, __.__(Double.NaN).asBool().next());
+        assertEquals(false, __.__(null).asBool().next());
+        assertEquals(true, __.__("TRUE").asBool().next());
+        assertEquals(false, __.__("false").asBool().next());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void shouldThrowOnInvalidString() {
+        __.__("hello").asBool().next();
+    }
+}
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs 
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
index ef645da751..d9091d1afb 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GraphTraversal.cs
@@ -251,6 +251,15 @@ namespace Gremlin.Net.Process.Traversal
             return Wrap<TStart, DateTimeOffset>(this);
         }
 
+        /// <summary>
+        ///     Adds the asBool step to this <see cref="GraphTraversal{SType, 
EType}" />.
+        /// </summary>
+        public GraphTraversal<TStart, bool> AsBool()
+        {
+            Bytecode.AddStep("asBool");
+            return Wrap<TStart, bool>(this);
+        }
+
         /// <summary>
         ///     Adds the barrier step to this <see cref="GraphTraversal{SType, 
EType}" />.
         /// </summary>
diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs 
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
index 1e1995caad..7e077f7fc5 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/__.cs
@@ -176,6 +176,14 @@ namespace Gremlin.Net.Process.Traversal
             return new GraphTraversal<object, DateTimeOffset>().AsDate();
         }
 
+        /// <summary>
+        ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds 
the asBool step to that traversal.
+        /// </summary>
+        public static GraphTraversal<object, bool> AsBool()
+        {
+            return new GraphTraversal<object, bool>().AsBool();
+        }
+
         /// <summary>
         ///     Spawns a <see cref="GraphTraversal{SType, EType}" /> and adds 
the barrier step to that traversal.
         /// </summary>
diff --git a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs 
b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
index 5908c0d966..557b6d48bc 100644
--- a/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.IntegrationTest/Gherkin/Gremlin.cs
@@ -618,11 +618,15 @@ namespace Gremlin.Net.IntegrationTest.Gherkin
                {"g_injectXstr_offsetX_asDate", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>("2023-08-02T00:00:00-07:00").AsDate()}}, 
                {"g_injectX1694017707000X_asDate", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(1694017707000).AsDate()}}, 
                {"g_injectX1694017708000LX_asDate", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(p["xx1"]).AsDate()}}, 
-               {"g_injectX1694017709000dX_asDate", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(p["xx1"]).AsDate()}}, 
-               {"g_injectX1_2X_asDate", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(p["xx1"]).AsDate()}}, 
-               {"g_injectXnullX_asDate", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(null).AsDate()}}, 
-               {"g_injectXinvalidstrX_asDate", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>("This String is not an ISO 8601 Date").AsDate()}}, 
-               {"g_injectX1_2X_asString", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"], 
p["xx2"]).AsString()}}, 
+               {"g_injectX1694017709000dX_asDate", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(p["xx1"]).AsDate()}},
+               {"g_injectX1_2X_asDate", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(p["xx1"]).AsDate()}},
+               {"g_injectXnullX_asDate", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(null).AsDate()}},
+               {"g_injectXinvalidstrX_asDate", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>("This String is not an ISO 8601 Date").AsDate()}},
+               {"g_injectX1X_asBool", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(1).AsBool()}},
+               {"g_injectX0X_asBool", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) 
=>g.Inject<object>(0).AsBool()}},
+               {"g_injectXstr_trueX_asBool", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>("true").AsBool()}},
+               {"g_injectXinvalidstrX_asBool", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>("hello").AsBool()}},
+               {"g_injectX1_2X_asString", new List<Func<GraphTraversalSource, 
IDictionary<string, object>, ITraversal>> {(g,p) =>g.Inject<object>(p["xx1"], 
p["xx2"]).AsString()}},
                {"g_injectX1_2X_asStringXlocalX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(p["xx1"], p["xx2"]).AsString<object>(Scope.Local)}}, 
                {"g_injectXlist_1_2X_asStringXlocalX", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(p["xx1"]).AsString<object>(Scope.Local)}}, 
                {"g_injectX1_nullX_asString", new 
List<Func<GraphTraversalSource, IDictionary<string, object>, ITraversal>> 
{(g,p) =>g.Inject<object>(null, p["xx1"]).AsString()}}, 
diff --git a/gremlin-go/driver/anonymousTraversal.go 
b/gremlin-go/driver/anonymousTraversal.go
index a1b3a3f0b1..67b107ab07 100644
--- a/gremlin-go/driver/anonymousTraversal.go
+++ b/gremlin-go/driver/anonymousTraversal.go
@@ -383,7 +383,12 @@ func (anonymousTraversal *anonymousTraversal) As(args 
...interface{}) *GraphTrav
 
 // AsDate adds the AsDate step to the GraphTraversal.
 func (anonymousTraversal *anonymousTraversal) AsDate(args ...interface{}) 
*GraphTraversal {
-       return anonymousTraversal.graphTraversal().AsDate(args...)
+        return anonymousTraversal.graphTraversal().AsDate(args...)
+}
+
+// AsBool adds the AsBool step to the GraphTraversal.
+func (anonymousTraversal *anonymousTraversal) AsBool(args ...interface{}) 
*GraphTraversal {
+        return anonymousTraversal.graphTraversal().AsBool(args...)
 }
 
 // AsString adds the asString step to the GraphTraversal.
diff --git a/gremlin-go/driver/cucumber/gremlin.go 
b/gremlin-go/driver/cucumber/gremlin.go
index 1574cb18df..48f8833d28 100644
--- a/gremlin-go/driver/cucumber/gremlin.go
+++ b/gremlin-go/driver/cucumber/gremlin.go
@@ -591,8 +591,12 @@ var translationMap = map[string][]func(g 
*gremlingo.GraphTraversalSource, p map[
     "g_injectX1694017709000dX_asDate": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return g.Inject(p["xx1"]).AsDate()}}, 
     "g_injectX1_2X_asDate": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(p["xx1"]).AsDate()}}, 
     "g_injectXnullX_asDate": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(nil).AsDate()}}, 
-    "g_injectXinvalidstrX_asDate": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("This String 
is not an ISO 8601 Date").AsDate()}}, 
-    "g_injectX1_2X_asString": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"], 
p["xx2"]).AsString()}}, 
+    "g_injectXinvalidstrX_asDate": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject("This String 
is not an ISO 8601 Date").AsDate()}},
+    "g_injectX1X_asBool": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(1).AsBool()}},
+    "g_injectX0X_asBool": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject(0).AsBool()}},
+    "g_injectXstr_trueX_asBool": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject("true").AsBool()}},
+    "g_injectXinvalidstrX_asBool": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return 
g.Inject("hello").AsBool()}},
+    "g_injectX1_2X_asString": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"], 
p["xx2"]).AsString()}},
     "g_injectX1_2X_asStringXlocalX": {func(g *gremlingo.GraphTraversalSource, 
p map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(p["xx1"], 
p["xx2"]).AsString(gremlingo.Scope.Local)}}, 
     "g_injectXlist_1_2X_asStringXlocalX": {func(g 
*gremlingo.GraphTraversalSource, p map[string]interface{}) 
*gremlingo.GraphTraversal {return 
g.Inject(p["xx1"]).AsString(gremlingo.Scope.Local)}}, 
     "g_injectX1_nullX_asString": {func(g *gremlingo.GraphTraversalSource, p 
map[string]interface{}) *gremlingo.GraphTraversal {return g.Inject(nil, 
p["xx1"]).AsString()}}, 
diff --git a/gremlin-go/driver/graphTraversal.go 
b/gremlin-go/driver/graphTraversal.go
index c3f7fca266..c9096d5d59 100644
--- a/gremlin-go/driver/graphTraversal.go
+++ b/gremlin-go/driver/graphTraversal.go
@@ -108,8 +108,14 @@ func (g *GraphTraversal) As(args ...interface{}) 
*GraphTraversal {
 
 // AsDate adds the asDate step to the GraphTraversal.
 func (g *GraphTraversal) AsDate(args ...interface{}) *GraphTraversal {
-       g.Bytecode.AddStep("asDate", args...)
-       return g
+        g.Bytecode.AddStep("asDate", args...)
+        return g
+}
+
+// AsBool adds the asBool step to the GraphTraversal.
+func (g *GraphTraversal) AsBool(args ...interface{}) *GraphTraversal {
+        g.Bytecode.AddStep("asBool", args...)
+        return g
 }
 
 // AsString adds the asString step to the GraphTraversal.
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
index b2a831b038..e86dd4af47 100644
--- 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
+++ 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js
@@ -433,6 +433,16 @@ class GraphTraversal extends Traversal {
     return this;
   }
 
+  /**
+   * Graph traversal asBool method.
+   * @param {...Object} args
+   * @returns {GraphTraversal}
+   */
+  asBool(...args) {
+    this.bytecode.addStep('asBool', args);
+    return this;
+  }
+
   /**
    * Graph traversal asDate method.
    * @param {...Object} args
@@ -1740,6 +1750,7 @@ const statics = {
   and: (...args) => callOnEmptyTraversal('and', args),
   any: (...args) => callOnEmptyTraversal('any', args),
   as: (...args) => callOnEmptyTraversal('as', args),
+  asBool: (...args) => callOnEmptyTraversal('asBool', args),
   asDate: (...args) => callOnEmptyTraversal('asDate', args),
   asString: (...args) => callOnEmptyTraversal('asString', args),
   barrier: (...args) => callOnEmptyTraversal('barrier', args),
diff --git 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
index aab974e253..490e9da972 100644
--- 
a/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
+++ 
b/gremlin-javascript/src/main/javascript/gremlin-javascript/test/cucumber/gremlin.js
@@ -621,8 +621,12 @@ const gremlins = {
     g_injectX1694017709000dX_asDate: [function({g, xx1}) { return 
g.inject(xx1).asDate() }], 
     g_injectX1_2X_asDate: [function({g, xx1}) { return g.inject(xx1).asDate() 
}], 
     g_injectXnullX_asDate: [function({g}) { return g.inject(null).asDate() }], 
-    g_injectXinvalidstrX_asDate: [function({g}) { return g.inject("This String 
is not an ISO 8601 Date").asDate() }], 
-    g_injectX1_2X_asString: [function({g, xx1, xx2}) { return g.inject(xx1, 
xx2).asString() }], 
+    g_injectXinvalidstrX_asDate: [function({g}) { return g.inject("This String 
is not an ISO 8601 Date").asDate() }],
+    g_injectX1X_asBool: [function({g}) { return g.inject(1).asBool() }],
+    g_injectX0X_asBool: [function({g}) { return g.inject(0).asBool() }],
+    g_injectXstr_trueX_asBool: [function({g}) { return 
g.inject("true").asBool() }],
+    g_injectXinvalidstrX_asBool: [function({g}) { return 
g.inject("hello").asBool() }],
+    g_injectX1_2X_asString: [function({g, xx1, xx2}) { return g.inject(xx1, 
xx2).asString() }],
     g_injectX1_2X_asStringXlocalX: [function({g, xx1, xx2}) { return 
g.inject(xx1, xx2).asString(Scope.local) }], 
     g_injectXlist_1_2X_asStringXlocalX: [function({g, xx1}) { return 
g.inject(xx1).asString(Scope.local) }], 
     g_injectX1_nullX_asString: [function({g, xx1}) { return g.inject(null, 
xx1).asString() }], 
diff --git a/gremlin-language/src/main/antlr4/Gremlin.g4 
b/gremlin-language/src/main/antlr4/Gremlin.g4
index a2ae6fea14..6f4ee05b57 100644
--- a/gremlin-language/src/main/antlr4/Gremlin.g4
+++ b/gremlin-language/src/main/antlr4/Gremlin.g4
@@ -304,6 +304,7 @@ traversalMethod
     | traversalMethod_replace
     | traversalMethod_split
     | traversalMethod_substring
+    | traversalMethod_asBool
     | traversalMethod_asDate
     | traversalMethod_dateAdd
     | traversalMethod_dateDiff
@@ -358,6 +359,10 @@ traversalMethod_asString
     | K_ASSTRING LPAREN traversalScope RPAREN #traversalMethod_asString_Scope
     ;
 
+traversalMethod_asBool
+    : K_ASBOOL LPAREN RPAREN
+    ;
+
 traversalMethod_barrier
     : K_BARRIER LPAREN traversalSackMethod RPAREN 
#traversalMethod_barrier_Consumer
     | K_BARRIER LPAREN RPAREN #traversalMethod_barrier_Empty
@@ -1928,6 +1933,7 @@ K_ANY: 'any';
 K_AS: 'as';
 K_ASC: 'asc';
 K_ASDATE: 'asDate';
+K_ASBOOL: 'asBool';
 K_ASSTRING: 'asString';
 K_ASSIGN: 'assign';
 K_BARRIER: 'barrier';
diff --git 
a/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py 
b/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
index f1f55f089c..5ded8b3f53 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/graph_traversal.py
@@ -318,6 +318,10 @@ class GraphTraversal(Traversal):
         self.bytecode.add_step("asDate", *args)
         return self
 
+    def as_bool(self, *args):
+        self.gremlin_lang.add_step("asBool", *args)
+        return self
+
     def as_string(self, *args):
         self.bytecode.add_step("asString", *args)
         return self
@@ -1099,6 +1103,10 @@ class __(object, metaclass=MagicType):
     def as_date(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).as_date(*args)
 
+    @classmethod
+    def as_bool(cls, *args):
+        return cls.graph_traversal(None, None, GremlinLang()).as_bool(*args)
+
     @classmethod
     def as_string(cls, *args):
         return cls.graph_traversal(None, None, Bytecode()).as_string(*args)
@@ -1870,6 +1878,8 @@ def as_(*args):
 def as_date(*args):
     return __.as_date(*args)
 
+def as_bool(*args):
+    return __.as_bool(*args)
 
 def as_string(*args):
     return __.as_string(*args)
@@ -2415,6 +2425,8 @@ statics.add_static('as_', as_)
 
 statics.add_static('as_date', as_date)
 
+statics.add_static('as_bool', as_bool)
+
 statics.add_static('as_string', as_string)
 
 statics.add_static('barrier', barrier)
diff --git a/gremlin-python/src/main/python/radish/gremlin.py 
b/gremlin-python/src/main/python/radish/gremlin.py
index 27a45da568..c61a66f7b0 100644
--- a/gremlin-python/src/main/python/radish/gremlin.py
+++ b/gremlin-python/src/main/python/radish/gremlin.py
@@ -594,8 +594,12 @@ world.gremlins = {
     'g_injectX1694017709000dX_asDate': [(lambda g, 
xx1=None:g.inject(xx1).as_date())], 
     'g_injectX1_2X_asDate': [(lambda g, xx1=None:g.inject(xx1).as_date())], 
     'g_injectXnullX_asDate': [(lambda g:g.inject(None).as_date())], 
-    'g_injectXinvalidstrX_asDate': [(lambda g:g.inject('This String is not an 
ISO 8601 Date').as_date())], 
-    'g_injectX1_2X_asString': [(lambda g, xx1=None,xx2=None:g.inject(xx1, 
xx2).as_string())], 
+    'g_injectXinvalidstrX_asDate': [(lambda g:g.inject('This String is not an 
ISO 8601 Date').as_date())],
+    'g_injectX1X_asBool': [(lambda g:g.inject(1).as_bool())],
+    'g_injectX0X_asBool': [(lambda g:g.inject(0).as_bool())],
+    'g_injectXstr_trueX_asBool': [(lambda g:g.inject('true').as_bool())],
+    'g_injectXinvalidstrX_asBool': [(lambda g:g.inject('hello').as_bool())],
+    'g_injectX1_2X_asString': [(lambda g, xx1=None,xx2=None:g.inject(xx1, 
xx2).as_string())],
     'g_injectX1_2X_asStringXlocalX': [(lambda g, 
xx1=None,xx2=None:g.inject(xx1, xx2).as_string(Scope.local))], 
     'g_injectXlist_1_2X_asStringXlocalX': [(lambda g, 
xx1=None:g.inject(xx1).as_string(Scope.local))], 
     'g_injectX1_nullX_asString': [(lambda g, xx1=None:g.inject(None, 
xx1).as_string())], 
diff --git 
a/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsBool.feature
 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsBool.feature
new file mode 100644
index 0000000000..93f9381464
--- /dev/null
+++ 
b/gremlin-test/src/main/resources/org/apache/tinkerpop/gremlin/test/features/map/AsBool.feature
@@ -0,0 +1,65 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+@StepClassMap @StepAsBool
+Feature: Step - asBool()
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX1X_asBool
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(1).asBool()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | true |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectX0X_asBool
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject(0).asBool()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | false |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXstr_trueX_asBool
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject('true').asBool()
+      """
+    When iterated to list
+    Then the result should be unordered
+      | result |
+      | true |
+
+  @GraphComputerVerificationInjectionNotSupported
+  Scenario: g_injectXinvalidstrX_asBool
+    Given the empty graph
+    And the traversal of
+      """
+      g.inject('hello').asBool()
+      """
+    When iterated to list
+    Then the traversal will raise an error with message containing text of 
"Can't parse"


Reply via email to