Skip to content

Commit 6cce0a3

Browse files
committed
Add Pagination and Slice Range Examples
1 parent 0f7d53a commit 6cce0a3

File tree

9 files changed

+132
-7
lines changed

9 files changed

+132
-7
lines changed

pages/examples/arraylist.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: ArrayList
33
parent: Examples
4-
nav_order: 7
4+
nav_order: 9
55
permalink: /examples/arraylist/
66
description: An external refinement for ArrayList that prevents out-of-bounds access.
77
---

pages/examples/connection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Connection
33
parent: Examples
4-
nav_order: 6
4+
nav_order: 8
55
permalink: /examples/connection/
66
description: A typestate protocol with a value-dependent conditional transition.
77
---

pages/examples/downloader.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Downloader
33
parent: Examples
4-
nav_order: 5
4+
nav_order: 7
55
permalink: /examples/downloader/
66
description: A typestate protocol for a downloader object.
77
---

pages/examples/email.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Email
33
parent: Examples
4-
nav_order: 3
4+
nav_order: 5
55
permalink: /examples/email/
66
description: A typestate protocol for a Email builder API.
77
---

pages/examples/media-player.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Media Player
33
parent: Examples
4-
nav_order: 2
4+
nav_order: 4
55
permalink: /examples/media-player/
66
description: A typestate protocol for a simple media player.
77
---

pages/examples/order.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Order
33
parent: Examples
4-
nav_order: 4
4+
nav_order: 6
55
permalink: /examples/order/
66
description: A typestate protocol for a simple order processing system.
77
---

pages/examples/pagination.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Pagination
3+
parent: Examples
4+
nav_order: 2
5+
permalink: /examples/pagination/
6+
description: Plain refinements with aliases for page numbers, page sizes, and computed offsets.
7+
---
8+
9+
# Pagination
10+
11+
This example uses plain refinements and refinement aliases to describe common pagination rules. The aliases keep the contracts readable while still relating results to the input values.
12+
13+
```java
14+
import liquidjava.specification.*;
15+
16+
@RefinementAlias("Page(int p) { p >= 1 }")
17+
@RefinementAlias("PageSize(int s) { 1 <= s && s <= 100 }")
18+
@RefinementAlias("ItemCount(int n) { n >= 0 }")
19+
public class Pagination {
20+
@Refinement("ItemCount(_) && _ == (page - 1) * size")
21+
public static int offset(
22+
@Refinement("Page(_)") int page,
23+
@Refinement("PageSize(_)") int size
24+
) {
25+
return (page - 1) * size;
26+
}
27+
28+
@Refinement("Page(_) && _ == page + 1")
29+
public static int nextPage(@Refinement("Page(_)") int page) {
30+
return page + 1;
31+
}
32+
33+
@Refinement("Page(_) && _ == (items + size - 1) / size")
34+
public static int totalPages(
35+
@Refinement("_ > 0") int items,
36+
@Refinement("PageSize(_)") int size
37+
) {
38+
return (items + size - 1) / size;
39+
}
40+
}
41+
```
42+
43+
```java
44+
int size = 20;
45+
int page = 3;
46+
int offset = Pagination.offset(page, size);
47+
int next = Pagination.nextPage(page);
48+
int total = Pagination.totalPages(50, size);
49+
```
50+
51+
```java
52+
Pagination.offset(0, 20); // Refinement Error
53+
```
54+
55+
```java
56+
Pagination.totalPages(50, 200); // Refinement Error
57+
```
58+
59+
The aliases capture the key domain concepts for pagination:
60+
61+
- `Page` says page numbers start at `1`
62+
- `PageSize` constrains the accepted page size range
63+
- `ItemCount` marks non-negative counts such as offsets

pages/examples/reentrant-lock.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: ReentrantLock
33
parent: Examples
4-
nav_order: 7
4+
nav_order: 10
55
permalink: /examples/reentrant-lock/
66
description: An external typestate refinement for ReentrantLock.
77
---

pages/examples/slice-range.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: Slice Range
3+
parent: Examples
4+
nav_order: 3
5+
permalink: /examples/slice-range/
6+
description: Plain refinements with aliases for valid index ranges and slice lengths.
7+
---
8+
9+
# Slice Range
10+
11+
This example models a small utility for working with array slices. It uses plain refinements and aliases with multiple parameters to encode reusable range checks.
12+
13+
```java
14+
import liquidjava.specification.*;
15+
16+
@RefinementAlias("Length(int n) { n >= 0 }")
17+
@RefinementAlias("ValidIndex(int i, int size) { 0 <= i && i < size }")
18+
@RefinementAlias("ValidRange(int start, int end, int size) { 0 <= start && start <= end && end <= size }")
19+
public class SliceRange {
20+
@Refinement("Length(_) && _ == end - start")
21+
public static int sliceLength(
22+
@Refinement("Length(size)") int size,
23+
int start,
24+
@Refinement("ValidRange(start, end, size)") int end
25+
) {
26+
return end - start;
27+
}
28+
29+
@Refinement("ValidIndex(_, size)")
30+
public static int lastIndex(@Refinement("size > 0") int size) {
31+
return size - 1;
32+
}
33+
34+
@Refinement("Length(_) && _ == index + 1")
35+
public static int prefixLength(
36+
@Refinement("Length(size)") int size,
37+
@Refinement("ValidIndex(index, size)") int index
38+
) {
39+
return index + 1;
40+
}
41+
}
42+
```
43+
44+
```java
45+
int size = 10;
46+
int part = SliceRange.sliceLength(size, 2, 6);
47+
int last = SliceRange.lastIndex(size);
48+
int prefix = SliceRange.prefixLength(size, 4);
49+
```
50+
51+
```java
52+
SliceRange.sliceLength(10, 7, 3); // Refinement Error
53+
```
54+
55+
```java
56+
SliceRange.prefixLength(10, 10); // Refinement Error
57+
```
58+
59+
The aliases capture the key domain concepts for working with slices:
60+
- `Length` says lengths are non-negative
61+
- `ValidIndex` says an index is valid if it is within the bounds of the size
62+
- `ValidRange` says a range is valid if it starts and ends within the bounds of the size, and the start is not after the end

0 commit comments

Comments
 (0)