on master help sign in
Initial commit
commitee9188d42aaeeec05a60c0351eff2bbd2680b00c authoriko <ilyakooo0@gmail.com> dateWed 29 May 2019, 01:29 (7 years ago) parent78d77bc
13 files changed+350−1
unifiedsplit
README.md+37−1 arguments/ArgumentParser.java+32 arguments/ComplexParsable.java+40 arguments/ComplexParser.java+8 arguments/InetParser.java+40 arguments/IntParser.java+22 arguments/Pair.java+11 arguments/Parsable.java+9 arguments/SimpleParsable.java+67 arguments/SimpleParser.java+6 arguments/SocketParser.java+45 arguments/StringParser.java+19 arguments/Tripplet.java+14
README.md+37−1
@@ -1,2 +1,38 @@
11# rasparsit
2−Declarative, composable and extensible command line argument parser for Java
2+
3+## A type safe, declarative, composable and extensible command line argument parser for Java.
4+
5+I was pretty sure at some point that you can use `ArgumentParser` in places of `SimpleParser` and `ComplexParser` and it would pretty much work as intended. This is what I meant by composable.
6+
7+### Examples
8+
9+```java
10+final ArgumentParser<SimpleParsable<Integer>, ArgumentParser<SimpleParsable<Integer>, ArgumentParser<ComplexParsable<Socket>, ArgumentParser>>> parser =
11+ new ArgumentParser<>(new SimpleParsable<Integer>(IntParser.parser, n -> n > 0, "You did not provide a valid positive list half-size."),
12+ new ArgumentParser<>(new SimpleParsable<Integer>(IntParser.parser, m -> m > 0, "You did not provide a valid positive integer upper-bound."),
13+ new ArgumentParser<>(new ComplexParsable<>(SocketParser.parser), null)));
14+
15+Pair<String, List<String>> result = parser.parse(Arrays.asList(args));
16+
17+if (result.fst != null) {
18+ System.out.println(result.fst);
19+ System.exit(1);
20+}
21+
22+final int maxInt = parser.value.value;
23+final int intCount = parser.next.value.value;
24+final Socket socket = parser.next.next.value.value;
25+```
26+
27+```java
28+final SimpleParsable<Integer> parser = new SimpleParsable<Integer>(IntParser.parser,
29+ p -> p >= 0 && p <= 65535,
30+ "Could not parse port");
31+
32+final Pair<String, List<String>> patseResult = parser.parse(new ArrayList<>(Arrays.asList(args)));
33+
34+if (patseResult.fst != null) {
35+ System.out.println(patseResult.fst);
36+ System.exit(1);
37+}
38+```
arguments/ArgumentParser.javanew file+32
@@ -0,0 +1,32 @@
1+package app.arguments;
2+
3+import org.jetbrains.annotations.NotNull;
4+
5+import java.util.List;
6+
7+public class ArgumentParser<@NotNull T extends Parsable, R extends Parsable> implements Parsable {
8+ public final T value;
9+ public final R next;
10+
11+ @NotNull
12+ @Override
13+ public Pair<String, List<String>> parse(@NotNull List<String> arguments) {
14+ final Pair<String, List<String>> result = value.parse(arguments);
15+
16+ if (result.fst == null && next != null) {
17+ return next.parse(result.snd);
18+ }
19+
20+ return result;
21+ }
22+
23+ public ArgumentParser(T value, R next) {
24+ this.value = value;
25+ this.next = next;
26+ }
27+
28+ public ArgumentParser(T value) {
29+ this.value = value;
30+ this.next = null;
31+ }
32+}
arguments/ComplexParsable.javanew file+40
@@ -0,0 +1,40 @@
1+package app.arguments;
2+
3+import org.jetbrains.annotations.NotNull;
4+
5+import java.util.List;
6+import java.util.function.Predicate;
7+
8+public class ComplexParsable<Self> implements Parsable {
9+ @NotNull
10+ private ComplexParser<Self> parseValue;
11+
12+ public Self value;
13+ private final @NotNull Predicate<@NotNull Self> predicate;
14+
15+ @Override
16+ public @NotNull Pair<String, List<String>> parse(@NotNull List<String> arguments) {
17+ Tripplet<String, @NotNull Self, @NotNull List<@NotNull String>> result = parseValue.apply(arguments);
18+
19+ if (result.fst == null) {
20+ value = result.snd;
21+
22+ if (predicate.test(value)) {
23+ return new Pair<>(null, result.thrd);
24+ }
25+ }
26+
27+ return new Pair<>(result.fst, result.thrd);
28+
29+ }
30+
31+ public ComplexParsable(@NotNull ComplexParser<Self> parseValue,
32+ @NotNull Predicate<@NotNull Self> predicate) {
33+ this.parseValue = parseValue;
34+ this.predicate = predicate;
35+ }
36+
37+ public ComplexParsable(@NotNull ComplexParser<Self> parseValue) {
38+ this(parseValue, i -> true);
39+ }
40+}
arguments/ComplexParser.javanew file+8
@@ -0,0 +1,8 @@
1+package app.arguments;
2+
3+import org.jetbrains.annotations.NotNull;
4+
5+import java.util.List;
6+import java.util.function.Function;
7+
8+public interface ComplexParser<Self> extends Function<List<String>, @NotNull Tripplet<String, Self, List<String>>> {}
arguments/InetParser.javanew file+40
@@ -0,0 +1,40 @@
1+package app.arguments;
2+
3+import org.jetbrains.annotations.NotNull;
4+
5+import java.net.InetAddress;
6+import java.net.UnknownHostException;
7+import java.util.List;
8+
9+public class InetParser implements ComplexParser<InetAddress> {
10+ public static final InetParser parser = new InetParser();
11+
12+ private InetParser() {}
13+
14+ @Override
15+ public @NotNull Tripplet<String, InetAddress, List<String>> apply(List<String> strings) {
16+ if (strings.size() < 1) {
17+ return new Tripplet<>("Could not parse inet address.", null, strings);
18+ }
19+
20+ SimpleParsable<String> hostParser =
21+ new SimpleParsable<>(StringParser.parser,
22+ "Could not parse host.");
23+
24+ Pair<String, List<String>> result = hostParser.parse(strings);
25+
26+ if (result.fst != null) {
27+ return new Tripplet<>(result.fst, null, result.snd);
28+ }
29+
30+ InetAddress address;
31+
32+ try {
33+ address = InetAddress.getByName(hostParser.value);
34+ } catch (UnknownHostException e) {
35+ return new Tripplet<>("Could not initialize the inet address", null, result.snd);
36+ }
37+
38+ return new Tripplet<>(null, address, result.snd);
39+ }
40+}
arguments/IntParser.javanew file+22
@@ -0,0 +1,22 @@
1+package app.arguments;
2+
3+import java.util.List;
4+
5+public class IntParser implements SimpleParser<Integer> {
6+ public static final IntParser parser = new IntParser();
7+
8+ private IntParser() {}
9+
10+ @Override
11+ public Pair<Integer, List<String>> apply(List<String> arguments) {
12+ if (arguments.size() < 1) {
13+ return null;
14+ }
15+
16+ try {
17+ return new Pair<>(Integer.parseInt(arguments.get(0)), arguments.subList(1, arguments.size()));
18+ } catch (Exception ignored) {
19+ return null;
20+ }
21+ }
22+}
arguments/Pair.javanew file+11
@@ -0,0 +1,11 @@
1+package app.arguments;
2+
3+public class Pair<T, H> {
4+ public final T fst;
5+ public final H snd;
6+
7+ Pair(T fst, H snd) {
8+ this.fst = fst;
9+ this.snd = snd;
10+ }
11+}
arguments/Parsable.javanew file+9
@@ -0,0 +1,9 @@
1+package app.arguments;
2+
3+import org.jetbrains.annotations.NotNull;
4+
5+import java.util.List;
6+
7+public interface Parsable {
8+ @NotNull Pair<String, List<String>> parse(@NotNull List<String> arguments);
9+}
arguments/SimpleParsable.javanew file+67
@@ -0,0 +1,67 @@
1+package app.arguments;
2+
3+import org.jetbrains.annotations.NotNull;
4+
5+import java.util.List;
6+import java.util.function.Predicate;
7+
8+public class SimpleParsable<Self> implements Parsable {
9+ @NotNull
10+ private SimpleParser<Self> parseValue;
11+
12+ public Self value;
13+
14+ private final @NotNull Predicate<@NotNull Self> predicate;
15+ private final Self def;
16+ private final @NotNull String message;
17+
18+ @NotNull
19+ @Override
20+ public Pair<String, List<String>> parse(@NotNull List<String> arguments) {
21+ Pair<@NotNull Self, @NotNull List<@NotNull String>> result = parseValue.apply(arguments);
22+
23+ if (result != null) {
24+ value = result.fst;
25+
26+ if (predicate.test(value)) {
27+ return new Pair<>(null, result.snd);
28+ }
29+ }
30+
31+ if (def != null) {
32+ value = def;
33+
34+ if (predicate.test(value)) {
35+ return new Pair<>(null, arguments);
36+ }
37+ }
38+
39+ return new Pair<>(message, arguments);
40+ }
41+
42+ public SimpleParsable(
43+ @NotNull SimpleParser<Self> parseValue,
44+ Self def,
45+ @NotNull Predicate<@NotNull Self> predicate,
46+ @NotNull String message) {
47+ this.parseValue = parseValue;
48+ this.predicate = predicate;
49+ this.def = def;
50+ this.message = message;
51+ }
52+
53+ public SimpleParsable(@NotNull SimpleParser<Self> parseValue,
54+ @NotNull Predicate<@NotNull Self> predicate,
55+ @NotNull String message) {
56+ this(parseValue, null, predicate, message);
57+ }
58+
59+
60+ public SimpleParsable(@NotNull SimpleParser<Self> parseValue, Self def, @NotNull String message) {
61+ this(parseValue, def, (i) -> true, message);
62+ }
63+
64+ public SimpleParsable(@NotNull SimpleParser<Self> parseValue, @NotNull String message) {
65+ this(parseValue, null, (i) -> true, message);
66+ }
67+}
arguments/SimpleParser.javanew file+6
@@ -0,0 +1,6 @@
1+package app.arguments;
2+
3+import java.util.List;
4+import java.util.function.Function;
5+
6+public interface SimpleParser<Self> extends Function<List<String>, Pair<Self, List<String>>> {}
arguments/SocketParser.javanew file+45
@@ -0,0 +1,45 @@
1+package app.arguments;
2+
3+import org.jetbrains.annotations.NotNull;
4+
5+import java.io.IOException;
6+import java.net.InetAddress;
7+import java.net.Socket;
8+import java.util.List;
9+
10+public class SocketParser implements ComplexParser<Socket> {
11+ public static final SocketParser parser = new SocketParser();
12+
13+ private SocketParser() {}
14+
15+ @Override
16+ public @NotNull Tripplet<String, Socket, List<String>> apply(List<String> strings) {
17+ SimpleParsable<Integer> portParser =
18+ new SimpleParsable<Integer>(IntParser.parser,
19+ p -> p >= 0 && p <= 65535,
20+ "Could not parse port");
21+
22+ ArgumentParser<
23+ ComplexParsable<InetAddress>,
24+ @NotNull ArgumentParser<
25+ SimpleParsable<Integer>, ArgumentParser>> parser =
26+ new ArgumentParser<>(new ComplexParsable<>(InetParser.parser),
27+ new ArgumentParser<>(portParser));
28+
29+ Pair<String, List<String>> result = parser.parse(strings);
30+
31+ if (result.fst != null) {
32+ return new Tripplet<>(result.fst, null, result.snd);
33+ }
34+
35+ Socket socket;
36+
37+ try {
38+ socket = new Socket(parser.value.value, parser.next.value.value);
39+ } catch (IOException e) {
40+ return new Tripplet<>("Could not initialize socket.", null, result.snd);
41+ }
42+
43+ return new Tripplet<>(null, socket, result.snd);
44+ }
45+}
arguments/StringParser.javanew file+19
@@ -0,0 +1,19 @@
1+package app.arguments;
2+
3+import java.util.List;
4+
5+public class StringParser implements SimpleParser<String> {
6+
7+ public static final StringParser parser = new StringParser();
8+
9+ private StringParser() {}
10+
11+ @Override
12+ public Pair<String, List<String>> apply(List<String> strings) {
13+ if (strings.size() < 1) {
14+ return null;
15+ } else {
16+ return new Pair<>(null, strings.subList(1, strings.size()));
17+ }
18+ }
19+}
arguments/Tripplet.javanew file+14
@@ -0,0 +1,14 @@
1+package app.arguments;
2+
3+public class Tripplet<T, H, U> {
4+
5+ public final T fst;
6+ public final H snd;
7+ public final U thrd;
8+
9+ Tripplet(T fst, H snd, U thrd) {
10+ this.fst = fst;
11+ this.snd = snd;
12+ this.thrd = thrd;
13+ }
14+}