Skip to content

Commit 8f7ffa2

Browse files
committed
Fix bug when processing prefix 32 from input
1 parent f4f40b2 commit 8f7ffa2

File tree

4 files changed

+58
-14
lines changed

4 files changed

+58
-14
lines changed

src/components/parts/IPv4Input.svelte

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
<!-- @component
22
A convenient addition to allow pasting/editing as whole
33
-->
4-
<script context="module" lang="ts">
4+
<script lang="ts">
55
import { pattern, parseFrom } from '@lib/ipv4';
6-
</script>
6+
import Toast from './Toast.svelte';
77
8-
<script lang="ts">
98
export let address = 0xc0a80000;
109
export let renderedAddress = 'placeholder';
1110
export let prefix = 16;
@@ -23,16 +22,24 @@ A convenient addition to allow pasting/editing as whole
2322
elm.select();
2423
};
2524
25+
let toast: string | null = null;
26+
2627
const evaluate = () => {
27-
const { address: addr, prefix: pref } = parseFrom(inputAsWhole);
28-
const isValid = addr > 0 && pref > 0;
28+
const { address: addr, prefix: pref, msg } = parseFrom(inputAsWhole);
29+
const isValid = addr > -1 && pref > -1;
2930
3031
if (!isValid) {
3132
return;
3233
}
3334
3435
address = addr;
3536
prefix = pref;
37+
38+
// give feedback on changes from actual input
39+
if (msg) {
40+
inputAsWhole = placeholder; // also update the input itself
41+
toast = msg;
42+
}
3643
};
3744
3845
const onBtnClick = () => {
@@ -56,6 +63,7 @@ A convenient addition to allow pasting/editing as whole
5663
};
5764
</script>
5865

66+
<Toast bind:text={toast} type="warning" />
5967
<div class="relative">
6068
<div class="absolute text-gray-600 left-5 top-2 lt-sm:top-5 lt-sm:left-0 lt-xs:top--1 z-30">
6169
<button

src/components/parts/Toast.svelte

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!-- @component
2+
A toast
3+
-->
4+
5+
<script lang="ts">
6+
export let text: string | null = null;
7+
export let durationInSec = 1;
8+
export let type = 'info';
9+
10+
const clearToast = (toast: string | null) => {
11+
if (toast) {
12+
setTimeout(() => {
13+
text = null;
14+
}, 1000 * durationInSec);
15+
}
16+
};
17+
18+
$: {
19+
clearToast(text);
20+
}
21+
</script>
22+
23+
<!-- safe list class="alert alert-info alert-success alert-warning alert-error" -->
24+
25+
<div class="toast toast-top toast-end z-50" class:hidden={!text}>
26+
<div class={`alert alert-${type}`}>
27+
<span>{text}</span>
28+
</div>
29+
</div>

src/lib/ipv4.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export const pattern = patternToTest.toString().slice(1, -1);
108108

109109
const failed = { address: -1, prefix: -1 };
110110

111-
export const parseFrom = (text: string) => {
111+
export const parseFrom = (text: string): { address: number; prefix: number; msg?: string } => {
112112
const passed = patternToTest.test(text);
113113

114114
if (!passed) return failed;
@@ -120,5 +120,12 @@ export const parseFrom = (text: string) => {
120120
const [a, b, c, d, prefix] = matched.slice(1).map((n) => Number(n));
121121
const address = assemble([a, b, c, d]);
122122

123-
return { address, prefix };
123+
const succeeded = { address, prefix };
124+
125+
if (prefix < 32) {
126+
return succeeded;
127+
}
128+
129+
// avoid calculating 32 as prefix as it doesn't seem to be useful and complicate the logics and UI
130+
return { address, prefix: 31, msg: `Prefix ${prefix} stepped down to 31` };
124131
};

test/lib/ipv4.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,46 @@ import { calcHosts, calcIP, assemble, parseFrom } from '../../src/lib/ipv4';
33

44
describe('parseFrom', () => {
55
it('1.2.3.4/5', () => {
6-
expect(parseFrom('1.2.3.4/5')).toEqual({ address: assemble([1, 2, 3, 4]), prefix: 5 });
6+
expect(parseFrom('1.2.3.4/5')).toContain({ address: assemble([1, 2, 3, 4]), prefix: 5 });
77
});
88

99
it('255.255.255.255/32', () => {
10-
expect(parseFrom('255.255.255.255/32')).toEqual({
10+
expect(parseFrom('255.255.255.255/32')).toContain({
1111
address: assemble([255, 255, 255, 255]),
1212
prefix: 32,
1313
});
1414
});
1515

1616
it('255.255.255.255/33', () => {
17-
expect(parseFrom('255.255.255.255/33')).toEqual({
17+
expect(parseFrom('255.255.255.255/33')).toContain({
1818
address: -1,
1919
prefix: -1,
2020
});
2121
});
2222

2323
it('256.255.255.255/32', () => {
24-
expect(parseFrom('256.255.255.255/32')).toEqual({
24+
expect(parseFrom('256.255.255.255/32')).toContain({
2525
address: -1,
2626
prefix: -1,
2727
});
2828
});
2929

3030
it('255.256.255.255/32', () => {
31-
expect(parseFrom('255.256.255.255/32')).toEqual({
31+
expect(parseFrom('255.256.255.255/32')).toContain({
3232
address: -1,
3333
prefix: -1,
3434
});
3535
});
3636

3737
it('255.255.256.255/32', () => {
38-
expect(parseFrom('255.255.256.255/32')).toEqual({
38+
expect(parseFrom('255.255.256.255/32')).toContain({
3939
address: -1,
4040
prefix: -1,
4141
});
4242
});
4343

4444
it('255.255.255.256/32', () => {
45-
expect(parseFrom('255.255.255.256/32')).toEqual({
45+
expect(parseFrom('255.255.255.256/32')).toContain({
4646
address: -1,
4747
prefix: -1,
4848
});

0 commit comments

Comments
 (0)