dupnamegen

Check-in Differences
Login

Check-in Differences

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From dupnamegen-0.1.1 To dupnamegen-0.2.0

2024-10-14
11:17
Make name generator closure Send. Leaf check-in: bb267b6ab2 user: jan tags: trunk, dupnamegen-0.2.0
08:23
Markdown fixups. check-in: 327fc52647 user: jan tags: trunk
08:22
Fix arrows. check-in: 49f67e2e8b user: jan tags: trunk
07:38
Release maintenance. check-in: d6801359ea user: jan tags: trunk, dupnamegen-0.1.1
07:36
Implement Debug for Naming. check-in: 28e0fc2f8a user: jan tags: trunk

Changes to Cargo.toml.

1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







[package]
name = "dupnamegen"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
license = "0BSD"
# https://crates.io/category_slugs
categories = [ "filesystem" ]
keywords = [ "filename", "generator" ]
repository = "https://repos.qrnch.tech/pub/dupnamegen"
description = "Sequential file name generator."

Changes to src/lib.rs.

51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66

67
68
69
70
71
72
73
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
73







-
+







-
+







/// [`Error::BadPath`] means that it wasn't possible to extract file name from
/// input path.  [`Error::NotUtf8`] means the file name can not be represented
/// as an utf-8 string.
pub fn namegen<P>(
  p: P,
  naming: Naming,
  start_idx: usize
) -> Result<Box<dyn FnMut() -> PathBuf>, Error>
) -> Result<Box<dyn FnMut() -> PathBuf + Send>, Error>
where
  P: AsRef<Path>
{
  fn inner(
    p: &Path,
    naming: Naming,
    start_idx: usize
  ) -> Result<Box<dyn FnMut() -> PathBuf>, Error> {
  ) -> Result<Box<dyn FnMut() -> PathBuf + Send>, Error> {
    let dir = p.parent().map(ToOwned::to_owned);
    let fname = p
      .file_name()
      .ok_or(Error::BadPath)?
      .to_str()
      .ok_or(Error::NotUtf8)?
      .to_owned();
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97







-
+







  inner(p, naming, start_idx)
}

fn winlike(
  dir: Option<PathBuf>,
  fname: String,
  start_idx: usize
) -> Box<dyn FnMut() -> PathBuf> {
) -> Box<dyn FnMut() -> PathBuf + Send> {
  // Find last `.' that is not at the first position
  // If no '.' -- stick the counter at the end
  let insert_at = fname.rfind('.').map_or(fname.len(), |idx| {
    if idx == 0 {
      // found a dot at first the very beginning
      // this is dotfile with no extension
      // stick the counter at the end
116
117
118
119
120
121
122
123

124
125
126
127
128
129
130
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







-
+







  })
}

fn firefoxlike(
  dir: Option<PathBuf>,
  fname: String,
  start_idx: usize
) -> Box<dyn FnMut() -> PathBuf> {
) -> Box<dyn FnMut() -> PathBuf + Send> {
  let insert_at = firefoxlike_find_index(&fname);

  let mut idx = start_idx;
  Box::new(move || {
    let mut nm = fname.clone();
    let sidx = format!("({idx})");
    nm.insert_str(insert_at, &sidx);
182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
202







-
+













  })
}

fn dashnum(
  dir: Option<PathBuf>,
  fname: String,
  start_idx: usize
) -> Box<dyn FnMut() -> PathBuf> {
) -> Box<dyn FnMut() -> PathBuf + Send> {
  let mut idx = start_idx;
  Box::new(move || {
    let nm = format!("{fname}-{idx}");
    idx += 1;
    if let Some(ref dir) = dir {
      dir.join(nm)
    } else {
      PathBuf::from(nm)
    }
  })
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :

Changes to www/changelog.md.

1
2
3
4
5
6
7

8
9
10
11
12
13
14










15
16
17
18
19
20
21
1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31






-
+







+
+
+
+
+
+
+
+
+
+







# Change Log

⚠️  indicates a breaking change.

## [Unreleased]

[Details](/vdiff?from=dupnamegen-0.1.1&to=trunk)
[Details](/vdiff?from=dupnamegen-0.2.0&to=trunk)

### Added

### Changed

### Removed

---

## [0.2.0] - 2024-10-14

[Details](/vdiff?from=dupnamegen-0.1.1&to=dupnamegen-0.2.0)

### Changed

- ⚠️ Add a `Send` bound to returned name generator closure.

---

## [0.1.1] - 2024-10-14

[Details](/vdiff?from=dupnamegen-0.1.0&to=dupnamegen-0.1.1)

### Added

Changes to www/index.md.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16


17
18
19


20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12

13
14


15
16
17


18
19
20
21
22
23
24
25
26












-
+

-
-
+
+

-
-
+
+







# dupnamegen

Generation of new file names, including a sequence number.  Useful when a
requested file name is already in use.


## Naming conventions
_dupnamegen_ supports three different naming conventions for generating new
file names.

- Windows-like
  - `Foo.zip` → `Foo (1).zip`
  - `lua-5.4.7.tar.gz` -> `lua-5.4.7.tar (1).gz`
  - `lua-5.4.7.tar.gz`  `lua-5.4.7.tar (1).gz`
- Firefox-like
  - `Foo.zip" → `Foo(1).zip`
  - `lua-5.4.7.tar.gz` -> `lua-5.4.7(1).tar.gz`
  - `Foo.zip` → `Foo(1).zip`
  - `lua-5.4.7.tar.gz`  `lua-5.4.7(1).tar.gz`
- Dash-num
  - `Foo.zip" → `Foo.zip-1`
  - `lua-5.4.7.tar.gz` -> `lua-5.4.7.tar.gz-1`
  - `Foo.zip` → `Foo.zip-1`
  - `lua-5.4.7.tar.gz`  `lua-5.4.7.tar.gz-1`


## Change log

The details of changes can always be found in the timeline, but for a
high-level view of changes between released versions there's a manually
maintained [Change Log](./changelog.md).