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
[package]
name = "dupnamegen"
version = "0.1.1"
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."


|







1
2
3
4
5
6
7
8
9
10
[package]
name = "dupnamegen"
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
/// [`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>
where
  P: AsRef<Path>
{
  fn inner(
    p: &Path,
    naming: Naming,
    start_idx: usize
  ) -> Result<Box<dyn FnMut() -> PathBuf>, 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();







|







|







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 + Send>, Error>
where
  P: AsRef<Path>
{
  fn inner(
    p: &Path,
    naming: Naming,
    start_idx: usize
  ) -> 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
  inner(p, naming, start_idx)
}

fn winlike(
  dir: Option<PathBuf>,
  fname: String,
  start_idx: usize
) -> Box<dyn FnMut() -> PathBuf> {
  // 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







|







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 + 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
  })
}

fn firefoxlike(
  dir: Option<PathBuf>,
  fname: String,
  start_idx: usize
) -> Box<dyn FnMut() -> PathBuf> {
  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);







|







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 + 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
  })
}

fn dashnum(
  dir: Option<PathBuf>,
  fname: String,
  start_idx: usize
) -> Box<dyn FnMut() -> PathBuf> {
  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 :







|













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 + 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
# Change Log

⚠️  indicates a breaking change.

## [Unreleased]

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

### Added

### Changed

### Removed











---

## [0.1.1] - 2024-10-14

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

### Added






|







>
>
>
>
>
>
>
>
>
>







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.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
# 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`
- Firefox-like
  - `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`


## 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).












|

|
|

|
|







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`
- Firefox-like
  - `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`


## 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).