A Java library for parsing and formatting Guava Range objects from string notation and JSON format.
Guava's Range class is powerful but lacks a built-in way to parse string notation back into Range objects. This library fills that gap by providing:
- String notation parsing: Parse
[0..100),(-∞..+∞), etc. into Range objects - Formatting: Convert Range objects back to string notation
- Jackson integration: Seamless JSON serialization/deserialization
- Spring Boot integration: Auto-configured converters for configuration properties
<!-- Core module (required) -->
<dependency>
<groupId>io.github.neewrobert</groupId>
<artifactId>guava-range-parser-core</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<!-- Jackson module (optional) -->
<dependency>
<groupId>io.github.neewrobert</groupId>
<artifactId>guava-range-parser-jackson</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
<!-- Spring Boot module (optional) -->
<dependency>
<groupId>io.github.neewrobert</groupId>
<artifactId>guava-range-parser-spring</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency><dependencyManagement>
<dependencies>
<dependency>
<groupId>io.github.neewrobert</groupId>
<artifactId>guava-range-parser-bom</artifactId>
<version>0.1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>import io.github.neewrobert.guavarangeparser.core.RangeParser;
import com.google.common.collect.Range;
// Parse integer ranges
Range<Integer> range = RangeParser.parse("[0..100)", Integer.class);
// Returns: Range.closedOpen(0, 100)
// Parse with infinity
Range<Integer> unbounded = RangeParser.parse("[100..+∞)", Integer.class);
// Returns: Range.atLeast(100)
// Parse duration ranges
Range<Duration> duration = RangeParser.parse("[PT1H..PT24H)", Duration.class);
// Returns: Range.closedOpen(Duration.ofHours(1), Duration.ofHours(24))import io.github.neewrobert.guavarangeparser.core.RangeFormatter;
String notation = RangeFormatter.toString(Range.closedOpen(0, 100));
// Returns: "[0..100)"
String unbounded = RangeFormatter.toString(Range.atLeast(100));
// Returns: "[100..+∞)"import io.github.neewrobert.guavarangeparser.jackson.GuavaRangeParserModule;
ObjectMapper mapper = new ObjectMapper()
.registerModule(new GuavaRangeParserModule());
// Deserialize
Range<Integer> range = mapper.readValue("\"[0..100)\"",
new TypeReference<Range<Integer>>() {});
// Serialize
String json = mapper.writeValueAsString(Range.closedOpen(0, 100));
// Returns: "[0..100)"Simply add the dependency and use Range types in your configuration:
@ConfigurationProperties(prefix = "my-app")
public class MyProperties {
private Range<Integer> stockRange;
private Range<Duration> refreshInterval;
// getters and setters
}my-app.stock-range=[0..100)
my-app.refresh-interval=[PT1M..PT5M]| Notation | Range Type | Description |
|---|---|---|
[a..b] |
closed(a, b) |
Both endpoints inclusive |
(a..b) |
open(a, b) |
Both endpoints exclusive |
[a..b) |
closedOpen(a, b) |
Lower inclusive, upper exclusive |
(a..b] |
openClosed(a, b) |
Lower exclusive, upper inclusive |
[a..+∞) |
atLeast(a) |
Lower bounded only |
(a..+∞) |
greaterThan(a) |
Greater than a |
(-∞..b] |
atMost(b) |
Upper bounded only |
(-∞..b) |
lessThan(b) |
Less than b |
(-∞..+∞) |
all() |
Unbounded |
- Numeric:
Integer,Long,Short,Byte,Double,Float,BigInteger,BigDecimal - Temporal:
Duration,Instant,LocalDate,LocalDateTime,LocalTime,ZonedDateTime,OffsetDateTime - Other:
String,Character
Register custom type adapters for your own Comparable types:
RangeParser parser = RangeParser.builder()
.registerType(Money.class, Money::parse)
.build();
Range<Money> range = parser.parseRange("[$10..$100)", Money.class);Choose how infinity is represented in output:
RangeFormatter formatter = RangeFormatter.builder()
.infinityStyle(InfinityStyle.SYMBOL) // +∞, -∞ (default)
.infinityStyle(InfinityStyle.WORD_LOWER) // +inf, -inf
.infinityStyle(InfinityStyle.WORD_UPPER) // +INF, -INF
.infinityStyle(InfinityStyle.WORD_FULL) // +Infinity, -Infinity
.build();Enable lenient mode to accept variations:
RangeParser parser = RangeParser.builder()
.lenient(true)
.build();
// All of these work in lenient mode:
parser.parseRange("[0..100)", Integer.class); // Standard
parser.parseRange("0..100", Integer.class); // No brackets (assumes closedOpen)mvn clean install- Java 17 or higher
- Guava 31 or higher
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Google Guava for the excellent Range API
- Inspired by Guava Issue #1911 and #2090