Fix completion bug

The reason why completion didn't work is that the parser didn't reject
"/ietf-system:system-" properly. It was able to parse the
ietf-system:system part but didn't care about the dash. In the end the
parser still failed, but completions did get created as if we were
already inside ietf-system:system (which were not because of the dash).
The fix is this: after a path fragment there can only be two things, a
slash or a "pathEnd" (which is a space or EOI). So, when I parse
ietf-system:system I check if that's the case. Otherwise, the parsing
failed, because we didn't parse the whole path fragment (because of the
dash in this case).

Issue: https://tree.taiga.io/project/jktjkt-netconf-cli/issue/208
Change-Id: I180308658af41e0ae119fcb17c75be9cce6aa764
diff --git a/src/ast_path.cpp b/src/ast_path.cpp
index 7ab9b18..9c77f35 100644
--- a/src/ast_path.cpp
+++ b/src/ast_path.cpp
@@ -272,6 +272,9 @@
             res = joinPaths(res, (prefixes == Prefixes::Always ? path.m_nodes.at(0).m_prefix.value().m_name + ":" : "") + std::visit(nodeToDataStringVisitor(), it.m_suffix));
         }
     }
+    if (path.m_trailingSlash == TrailingSlash::Present) {
+        res += "/";
+    }
 
     return res;
 }
diff --git a/src/path_parser.hpp b/src/path_parser.hpp
index c3df931..29dbd04 100644
--- a/src/path_parser.hpp
+++ b/src/path_parser.hpp
@@ -30,6 +30,7 @@
 x3::rule<createValueSuggestions_class, x3::unused_type> const createValueSuggestions = "createValueSuggestions";
 x3::rule<suggestKeysEnd_class, x3::unused_type> const suggestKeysEnd = "suggestKeysEnd";
 x3::rule<class leafListValue_class, leaf_data_> const leafListValue = "leafListValue";
+auto pathEnd = x3::rule<class PathEnd>{"pathEnd"} = &space_separator | x3::eoi;
 
 enum class NodeParserMode {
     CompleteDataNode,
@@ -218,7 +219,15 @@
             }
 
             if (res) {
-                parserContext.pushPathFragment(attr);
+                // After a path fragment, there can only be a slash or a "pathEnd". If this is not the case
+                // then that means there are other unparsed characters after the fragment. In that case the parsing
+                // needs to fail.
+                res = (pathEnd | &char_('/')).parse(begin, end, ctx, rctx, x3::unused);
+                if (!res) {
+                    begin = saveIter;
+                } else {
+                    parserContext.pushPathFragment(attr);
+                }
             }
 
             return res;
@@ -270,7 +279,6 @@
         initializePath.parse(begin, end, ctx, rctx, x3::unused);
         dataPath_ attrData;
 
-        auto pathEnd = x3::rule<class PathEnd>{"pathEnd"} = &space_separator | x3::eoi;
         // absoluteStart has to be separate from the dataPath parser,
         // otherwise, if the "dataNode % '/'" parser fails, the begin iterator
         // gets reverted to before the starting slash.