Skip to content

Commit a6b52e4

Browse files
fix(tauri-utils): include \n in io::read_line, closes #6388 (#6519)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio> fix(tauri-utils): include `\n` in `io::read_line`, closes #6388
1 parent 9edebbb commit a6b52e4

5 files changed

Lines changed: 82 additions & 53 deletions

File tree

‎.changes/tauri-utils-read-line.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri-utils': 'patch:bug'
3+
---
4+
5+
Fix `io::read_line` not including the new line character `\n`.

‎core/tauri-utils/src/io.rs‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use std::io::BufRead;
88

9-
/// Read a line breaking in both \n and \r.
9+
/// Read all bytes until a newline (the `0xA` byte) or a carriage return (`\r`) is reached, and append them to the provided buffer.
1010
///
1111
/// Adapted from <https://doc.rust-lang.org/std/io/trait.BufRead.html#method.read_line>.
1212
pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::Result<usize> {
@@ -16,6 +16,7 @@ pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::
1616
let available = match r.fill_buf() {
1717
Ok(n) => n,
1818
Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => continue,
19+
1920
Err(e) => return Err(e),
2021
};
2122
match memchr::memchr(b'\n', available) {
@@ -40,9 +41,6 @@ pub fn read_line<R: BufRead + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> std::io::
4041
r.consume(used);
4142
read += used;
4243
if done || used == 0 {
43-
if buf.ends_with(&[b'\n']) {
44-
buf.pop();
45-
}
4644
return Ok(read);
4745
}
4846
}

‎core/tauri/src/api/process/command.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ mod test {
468468
assert_eq!(payload.code, Some(1));
469469
}
470470
CommandEvent::Stderr(line) => {
471-
assert_eq!(line, "cat: test/api/: Is a directory".to_string());
471+
assert_eq!(line, "cat: test/api/: Is a directory\n".to_string());
472472
}
473473
_ => {}
474474
}

‎examples/api/dist/assets/index.js‎

Lines changed: 45 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎examples/api/src/views/Shell.svelte‎

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
let encoding = ''
1414
let stdin = ''
1515
let child
16+
let output = []
1617
1718
function _getEnv() {
1819
return env.split(' ').reduce((env, clause) => {
@@ -26,10 +27,11 @@
2627
2728
function spawn() {
2829
child = null
30+
output = []
2931
const command = new Command(cmd, [...args, script], {
3032
cwd: cwd || null,
3133
env: _getEnv(),
32-
encoding,
34+
encoding: encoding || null
3335
})
3436
3537
command.on('close', (data) => {
@@ -40,8 +42,23 @@
4042
})
4143
command.on('error', (error) => onMessage(`command error: "${error}"`))
4244
43-
command.stdout.on('data', (line) => onMessage(`command stdout: "${line}"`))
44-
command.stderr.on('data', (line) => onMessage(`command stderr: "${line}"`))
45+
function onOutput(line, kind) {
46+
onMessage(`command ${kind}: "${line}"`)
47+
48+
if (line.endsWith('\n')) {
49+
line = line.substring(0, line.length - 1)
50+
}
51+
52+
const last = output[output.length - 1]
53+
if (last && last.endsWith('\r')) {
54+
output = [...output.slice(0, output.length - 1), line]
55+
} else {
56+
output = [...output, line]
57+
}
58+
}
59+
60+
command.stdout.on('data', (line) => onOutput(line, 'stdout'))
61+
command.stderr.on('data', (line) => onOutput(line, 'stderr'))
4562
4663
command
4764
.spawn()
@@ -90,11 +107,19 @@
90107
</div>
91108
<div class="flex children:grow gap-1">
92109
<button class="btn" on:click={spawn}>Run</button>
93-
<button class="btn" on:click={kill}>Kill</button>
110+
{#if child}
111+
<button class="btn" on:click={kill}>Kill</button>
112+
{/if}
94113
</div>
95114
{#if child}
96115
<br />
97116
<input class="input" placeholder="write to stdin" bind:value={stdin} />
98117
<button class="btn" on:click={writeToStdin}>Write</button>
99118
{/if}
119+
120+
<div>
121+
{#each output as l}
122+
<p>{l}</p>
123+
{/each}
124+
</div>
100125
</div>

0 commit comments

Comments
 (0)