tangled
alpha
login
or
join now
davidpdrsn.tngl.sh
/
jj-sync-prs
1
fork
atom
this repo has no description
1
fork
atom
overview
issues
pulls
2
pipelines
Set title and description of created pr
davidpdrsn.tngl.sh
8 months ago
fc41ee46
f7e7a113
+191
-146
3 changed files
expand all
collapse all
unified
split
Cargo.lock
Cargo.toml
src
main.rs
+151
-123
Cargo.lock
···
33
33
]
34
34
35
35
[[package]]
36
36
-
name = "anstream"
37
37
-
version = "0.6.19"
38
38
-
source = "registry+https://github.com/rust-lang/crates.io-index"
39
39
-
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
40
40
-
dependencies = [
41
41
-
"anstyle",
42
42
-
"anstyle-parse",
43
43
-
"anstyle-query",
44
44
-
"anstyle-wincon",
45
45
-
"colorchoice",
46
46
-
"is_terminal_polyfill",
47
47
-
"utf8parse",
48
48
-
]
49
49
-
50
50
-
[[package]]
51
51
-
name = "anstyle"
52
52
-
version = "1.0.11"
53
53
-
source = "registry+https://github.com/rust-lang/crates.io-index"
54
54
-
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
55
55
-
56
56
-
[[package]]
57
57
-
name = "anstyle-parse"
58
58
-
version = "0.2.7"
59
59
-
source = "registry+https://github.com/rust-lang/crates.io-index"
60
60
-
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
61
61
-
dependencies = [
62
62
-
"utf8parse",
63
63
-
]
64
64
-
65
65
-
[[package]]
66
66
-
name = "anstyle-query"
67
67
-
version = "1.1.3"
68
68
-
source = "registry+https://github.com/rust-lang/crates.io-index"
69
69
-
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
70
70
-
dependencies = [
71
71
-
"windows-sys 0.59.0",
72
72
-
]
73
73
-
74
74
-
[[package]]
75
75
-
name = "anstyle-wincon"
76
76
-
version = "3.0.9"
77
77
-
source = "registry+https://github.com/rust-lang/crates.io-index"
78
78
-
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
79
79
-
dependencies = [
80
80
-
"anstyle",
81
81
-
"once_cell_polyfill",
82
82
-
"windows-sys 0.59.0",
83
83
-
]
84
84
-
85
85
-
[[package]]
86
36
name = "arc-swap"
87
37
version = "1.7.1"
88
38
source = "registry+https://github.com/rust-lang/crates.io-index"
···
175
125
]
176
126
177
127
[[package]]
178
178
-
name = "clap"
179
179
-
version = "4.5.41"
180
180
-
source = "registry+https://github.com/rust-lang/crates.io-index"
181
181
-
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
182
182
-
dependencies = [
183
183
-
"clap_builder",
184
184
-
"clap_derive",
185
185
-
]
186
186
-
187
187
-
[[package]]
188
188
-
name = "clap_builder"
189
189
-
version = "4.5.41"
190
190
-
source = "registry+https://github.com/rust-lang/crates.io-index"
191
191
-
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
192
192
-
dependencies = [
193
193
-
"anstream",
194
194
-
"anstyle",
195
195
-
"clap_lex",
196
196
-
"strsim",
197
197
-
]
198
198
-
199
199
-
[[package]]
200
200
-
name = "clap_derive"
201
201
-
version = "4.5.41"
202
202
-
source = "registry+https://github.com/rust-lang/crates.io-index"
203
203
-
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
204
204
-
dependencies = [
205
205
-
"heck",
206
206
-
"proc-macro2",
207
207
-
"quote",
208
208
-
"syn",
209
209
-
]
210
210
-
211
211
-
[[package]]
212
212
-
name = "clap_lex"
213
213
-
version = "0.7.5"
214
214
-
source = "registry+https://github.com/rust-lang/crates.io-index"
215
215
-
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
216
216
-
217
217
-
[[package]]
218
128
name = "color-eyre"
219
129
version = "0.6.5"
220
130
source = "registry+https://github.com/rust-lang/crates.io-index"
···
242
152
]
243
153
244
154
[[package]]
245
245
-
name = "colorchoice"
246
246
-
version = "1.0.4"
155
155
+
name = "console"
156
156
+
version = "0.15.11"
247
157
source = "registry+https://github.com/rust-lang/crates.io-index"
248
248
-
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
158
158
+
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
159
159
+
dependencies = [
160
160
+
"encode_unicode",
161
161
+
"libc",
162
162
+
"once_cell",
163
163
+
"unicode-width",
164
164
+
"windows-sys 0.59.0",
165
165
+
]
249
166
250
167
[[package]]
251
168
name = "core-foundation"
···
273
190
]
274
191
275
192
[[package]]
193
193
+
name = "dialoguer"
194
194
+
version = "0.11.0"
195
195
+
source = "registry+https://github.com/rust-lang/crates.io-index"
196
196
+
checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de"
197
197
+
dependencies = [
198
198
+
"console",
199
199
+
"shell-words",
200
200
+
"tempfile",
201
201
+
"thiserror 1.0.69",
202
202
+
"zeroize",
203
203
+
]
204
204
+
205
205
+
[[package]]
276
206
name = "displaydoc"
277
207
version = "0.2.5"
278
208
source = "registry+https://github.com/rust-lang/crates.io-index"
···
290
220
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
291
221
292
222
[[package]]
223
223
+
name = "encode_unicode"
224
224
+
version = "1.0.0"
225
225
+
source = "registry+https://github.com/rust-lang/crates.io-index"
226
226
+
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
227
227
+
228
228
+
[[package]]
229
229
+
name = "errno"
230
230
+
version = "0.3.13"
231
231
+
source = "registry+https://github.com/rust-lang/crates.io-index"
232
232
+
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
233
233
+
dependencies = [
234
234
+
"libc",
235
235
+
"windows-sys 0.59.0",
236
236
+
]
237
237
+
238
238
+
[[package]]
293
239
name = "eyre"
294
240
version = "0.6.12"
295
241
source = "registry+https://github.com/rust-lang/crates.io-index"
···
300
246
]
301
247
302
248
[[package]]
249
249
+
name = "fastrand"
250
250
+
version = "2.3.0"
251
251
+
source = "registry+https://github.com/rust-lang/crates.io-index"
252
252
+
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
253
253
+
254
254
+
[[package]]
303
255
name = "fnv"
304
256
version = "1.0.7"
305
257
source = "registry+https://github.com/rust-lang/crates.io-index"
···
412
364
"cfg-if",
413
365
"js-sys",
414
366
"libc",
415
415
-
"wasi",
367
367
+
"wasi 0.11.1+wasi-snapshot-preview1",
416
368
"wasm-bindgen",
369
369
+
]
370
370
+
371
371
+
[[package]]
372
372
+
name = "getrandom"
373
373
+
version = "0.3.3"
374
374
+
source = "registry+https://github.com/rust-lang/crates.io-index"
375
375
+
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
376
376
+
dependencies = [
377
377
+
"cfg-if",
378
378
+
"libc",
379
379
+
"r-efi",
380
380
+
"wasi 0.14.2+wasi-0.2.4",
417
381
]
418
382
419
383
[[package]]
···
698
662
]
699
663
700
664
[[package]]
701
701
-
name = "is_terminal_polyfill"
702
702
-
version = "1.70.1"
703
703
-
source = "registry+https://github.com/rust-lang/crates.io-index"
704
704
-
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
705
705
-
706
706
-
[[package]]
707
665
name = "itoa"
708
666
version = "1.0.15"
709
667
source = "registry+https://github.com/rust-lang/crates.io-index"
···
713
671
name = "jj-sync-prs"
714
672
version = "0.1.0"
715
673
dependencies = [
716
716
-
"clap",
717
674
"color-eyre",
675
675
+
"dialoguer",
718
676
"futures",
719
677
"octocrab",
720
678
"serde",
···
760
718
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
761
719
762
720
[[package]]
721
721
+
name = "linux-raw-sys"
722
722
+
version = "0.9.4"
723
723
+
source = "registry+https://github.com/rust-lang/crates.io-index"
724
724
+
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
725
725
+
726
726
+
[[package]]
763
727
name = "litemap"
764
728
version = "0.8.0"
765
729
source = "registry+https://github.com/rust-lang/crates.io-index"
···
803
767
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
804
768
dependencies = [
805
769
"libc",
806
806
-
"wasi",
770
770
+
"wasi 0.11.1+wasi-snapshot-preview1",
807
771
"windows-sys 0.59.0",
808
772
]
809
773
···
898
862
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
899
863
900
864
[[package]]
901
901
-
name = "once_cell_polyfill"
902
902
-
version = "1.70.1"
903
903
-
source = "registry+https://github.com/rust-lang/crates.io-index"
904
904
-
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
905
905
-
906
906
-
[[package]]
907
865
name = "openssl-probe"
908
866
version = "0.1.6"
909
867
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1020
978
]
1021
979
1022
980
[[package]]
981
981
+
name = "r-efi"
982
982
+
version = "5.3.0"
983
983
+
source = "registry+https://github.com/rust-lang/crates.io-index"
984
984
+
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
985
985
+
986
986
+
[[package]]
1023
987
name = "redox_syscall"
1024
988
version = "0.5.13"
1025
989
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1036
1000
dependencies = [
1037
1001
"cc",
1038
1002
"cfg-if",
1039
1039
-
"getrandom",
1003
1003
+
"getrandom 0.2.16",
1040
1004
"libc",
1041
1005
"untrusted",
1042
1006
"windows-sys 0.52.0",
···
1049
1013
checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
1050
1014
1051
1015
[[package]]
1016
1016
+
name = "rustix"
1017
1017
+
version = "1.0.7"
1018
1018
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1019
1019
+
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
1020
1020
+
dependencies = [
1021
1021
+
"bitflags",
1022
1022
+
"errno",
1023
1023
+
"libc",
1024
1024
+
"linux-raw-sys",
1025
1025
+
"windows-sys 0.59.0",
1026
1026
+
]
1027
1027
+
1028
1028
+
[[package]]
1052
1029
name = "rustls"
1053
1030
version = "0.23.28"
1054
1031
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1218
1195
]
1219
1196
1220
1197
[[package]]
1198
1198
+
name = "shell-words"
1199
1199
+
version = "1.1.0"
1200
1200
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1201
1201
+
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
1202
1202
+
1203
1203
+
[[package]]
1221
1204
name = "shlex"
1222
1205
version = "1.3.0"
1223
1206
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1240
1223
dependencies = [
1241
1224
"num-bigint",
1242
1225
"num-traits",
1243
1243
-
"thiserror",
1226
1226
+
"thiserror 2.0.12",
1244
1227
"time",
1245
1228
]
1246
1229
···
1294
1277
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
1295
1278
1296
1279
[[package]]
1297
1297
-
name = "strsim"
1298
1298
-
version = "0.11.1"
1299
1299
-
source = "registry+https://github.com/rust-lang/crates.io-index"
1300
1300
-
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
1301
1301
-
1302
1302
-
[[package]]
1303
1280
name = "subtle"
1304
1281
version = "2.6.1"
1305
1282
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1334
1311
]
1335
1312
1336
1313
[[package]]
1314
1314
+
name = "tempfile"
1315
1315
+
version = "3.20.0"
1316
1316
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1317
1317
+
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
1318
1318
+
dependencies = [
1319
1319
+
"fastrand",
1320
1320
+
"getrandom 0.3.3",
1321
1321
+
"once_cell",
1322
1322
+
"rustix",
1323
1323
+
"windows-sys 0.59.0",
1324
1324
+
]
1325
1325
+
1326
1326
+
[[package]]
1327
1327
+
name = "thiserror"
1328
1328
+
version = "1.0.69"
1329
1329
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1330
1330
+
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
1331
1331
+
dependencies = [
1332
1332
+
"thiserror-impl 1.0.69",
1333
1333
+
]
1334
1334
+
1335
1335
+
[[package]]
1337
1336
name = "thiserror"
1338
1337
version = "2.0.12"
1339
1338
source = "registry+https://github.com/rust-lang/crates.io-index"
1340
1339
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
1341
1340
dependencies = [
1342
1342
-
"thiserror-impl",
1341
1341
+
"thiserror-impl 2.0.12",
1342
1342
+
]
1343
1343
+
1344
1344
+
[[package]]
1345
1345
+
name = "thiserror-impl"
1346
1346
+
version = "1.0.69"
1347
1347
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1348
1348
+
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
1349
1349
+
dependencies = [
1350
1350
+
"proc-macro2",
1351
1351
+
"quote",
1352
1352
+
"syn",
1343
1353
]
1344
1354
1345
1355
[[package]]
···
1572
1582
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
1573
1583
1574
1584
[[package]]
1585
1585
+
name = "unicode-width"
1586
1586
+
version = "0.2.1"
1587
1587
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1588
1588
+
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
1589
1589
+
1590
1590
+
[[package]]
1575
1591
name = "untrusted"
1576
1592
version = "0.9.0"
1577
1593
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1596
1612
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
1597
1613
1598
1614
[[package]]
1599
1599
-
name = "utf8parse"
1600
1600
-
version = "0.2.2"
1601
1601
-
source = "registry+https://github.com/rust-lang/crates.io-index"
1602
1602
-
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
1603
1603
-
1604
1604
-
[[package]]
1605
1615
name = "valuable"
1606
1616
version = "0.1.1"
1607
1617
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1623
1633
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
1624
1634
1625
1635
[[package]]
1636
1636
+
name = "wasi"
1637
1637
+
version = "0.14.2+wasi-0.2.4"
1638
1638
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1639
1639
+
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
1640
1640
+
dependencies = [
1641
1641
+
"wit-bindgen-rt",
1642
1642
+
]
1643
1643
+
1644
1644
+
[[package]]
1626
1645
name = "wasm-bindgen"
1627
1646
version = "0.2.100"
1628
1647
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1831
1850
version = "0.52.6"
1832
1851
source = "registry+https://github.com/rust-lang/crates.io-index"
1833
1852
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
1853
1853
+
1854
1854
+
[[package]]
1855
1855
+
name = "wit-bindgen-rt"
1856
1856
+
version = "0.39.0"
1857
1857
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1858
1858
+
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
1859
1859
+
dependencies = [
1860
1860
+
"bitflags",
1861
1861
+
]
1834
1862
1835
1863
[[package]]
1836
1864
name = "writeable"
+1
-1
Cargo.toml
···
4
4
edition = "2024"
5
5
6
6
[dependencies]
7
7
-
clap = { version = "4.5.41", features = ["derive"] }
8
7
color-eyre = "0.6.5"
8
8
+
dialoguer = "0.11.0"
9
9
futures = "0.3.31"
10
10
octocrab = { version = "0.44.1", features = ["stream"] }
11
11
serde = { version = "1.0.219", features = ["derive"] }
+39
-22
src/main.rs
···
2
2
use std::pin::pin;
3
3
use std::{ffi::OsStr, path::Path};
4
4
5
5
-
use clap::Parser;
6
5
use color_eyre::eyre::{Context as _, ContextCompat};
6
6
+
use dialoguer::{Confirm, Editor};
7
7
use futures::TryStreamExt as _;
8
8
use octocrab::{Octocrab, models::pulls::PullRequest};
9
9
use serde::Deserialize;
···
12
12
13
13
mod graph;
14
14
15
15
-
#[derive(Parser, Debug)]
16
16
-
struct Cli {
17
17
-
#[arg(short, long)]
18
18
-
create_new: bool,
19
19
-
}
20
20
-
21
15
#[tokio::main(flavor = "current_thread")]
22
16
async fn main() -> color_eyre::Result<()> {
23
17
color_eyre::install()?;
24
24
-
25
25
-
let cli = Cli::parse();
26
18
27
19
let graph = build_branch_graph().context("failed to build graph")?;
28
20
···
47
39
48
40
for stack_root in graph.iter_edges_from("main") {
49
41
find_or_create_prs(
50
50
-
stack_root, "main", &graph, &repo_info, &octocrab, &cli, &mut pulls,
42
42
+
stack_root, "main", &graph, &repo_info, &octocrab, &mut pulls,
51
43
)
52
44
.await
53
45
.context("failed to sync prs")?;
···
221
213
graph: &Graph,
222
214
repo_info: &RepoInfo,
223
215
octocrab: &Octocrab,
224
224
-
cli: &Cli,
225
216
pulls: &mut Vec<PullRequest>,
226
217
) -> color_eyre::Result<()> {
227
227
-
find_or_create_pr(target, branch, pulls, octocrab, repo_info, cli)
218
218
+
find_or_create_pr(target, branch, pulls, octocrab, repo_info)
228
219
.await
229
220
.with_context(|| format!("failed to find or create pr from {branch} into {target}"))?;
230
221
231
222
for child in graph.iter_edges_from(branch) {
232
223
Box::pin(find_or_create_prs(
233
233
-
child, branch, graph, repo_info, octocrab, cli, pulls,
224
224
+
child, branch, graph, repo_info, octocrab, pulls,
234
225
))
235
226
.await
236
227
.with_context(|| format!("failed to find or create pr from {branch} into {target}"))?;
···
260
251
pulls: &mut Vec<PullRequest>,
261
252
octocrab: &Octocrab,
262
253
repo_info: &RepoInfo,
263
263
-
cli: &Cli,
264
254
) -> color_eyre::Result<()> {
265
255
if let Some((idx, pull)) = pulls
266
256
.iter()
···
290
280
})?;
291
281
pulls[idx] = updated;
292
282
}
293
293
-
} else if cli.create_new {
294
294
-
let pull = octocrab
295
295
-
.pulls(&repo_info.owner, &repo_info.name)
296
296
-
.create(branch, branch, target)
297
297
-
.draft(true)
298
298
-
.send()
299
299
-
.await
300
300
-
.with_context(|| format!("failed to create PR from {target}<-{branch}"))?;
283
283
+
} else if Confirm::new()
284
284
+
.with_prompt(format!(
285
285
+
"PR from {target}<-{branch} doesn't exist. Do you want to create it?"
286
286
+
))
287
287
+
.default(true)
288
288
+
.interact()?
289
289
+
{
290
290
+
let repo_pulls = octocrab.pulls(&repo_info.owner, &repo_info.name);
291
291
+
292
292
+
let pull = if let Some((title, body)) = get_pr_title_and_body()? {
293
293
+
repo_pulls.create(title, branch, target).body(body)
294
294
+
} else {
295
295
+
repo_pulls.create(branch, branch, target)
296
296
+
}
297
297
+
.draft(true)
298
298
+
.send()
299
299
+
.await
300
300
+
.with_context(|| format!("failed to create PR from {target}<-{branch}"))?;
301
301
+
301
302
if let Some(url) = &pull.html_url {
302
303
eprintln!("Created PR from {target}<-{branch}: {url}");
303
304
} else {
···
383
384
384
385
Ok(())
385
386
}
387
387
+
388
388
+
fn get_pr_title_and_body() -> color_eyre::Result<Option<(String, String)>> {
389
389
+
if let Some(text) = Editor::new()
390
390
+
.extension(".md")
391
391
+
.edit("Enter PR title...\n\n...and description here")?
392
392
+
{
393
393
+
let mut lines = text.lines();
394
394
+
let Some(title) = lines.next() else {
395
395
+
return Ok(None);
396
396
+
};
397
397
+
let msg = lines.skip(1).collect::<Vec<_>>().join("\n");
398
398
+
Ok(Some((title.to_owned(), msg)))
399
399
+
} else {
400
400
+
Ok(None)
401
401
+
}
402
402
+
}