Skip to content

Commit 7fb7d36

Browse files
authored
mark various things pub(crate)
Change various items from `pub` to `pub(crate)`. These items weren't actually public, since their modules weren't exported as pub. This doesn't change that, but it makes it clearer in the code. Also add a CI check (and a helper script) to ensure that I'll maintain this practice going forward. Resolves #383
1 parent 14eed27 commit 7fb7d36

30 files changed

+229
-192
lines changed

.github/workflows/rust.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,35 @@ jobs:
8383
- uses: actions/checkout@v4
8484
- name: cargo fmt
8585
run: cargo fmt --check
86+
87+
vis-keywords:
88+
needs: build
89+
runs-on: ubuntu-latest
90+
permissions:
91+
contents: read
92+
steps:
93+
- uses: actions/checkout@v4
94+
95+
- name: check file
96+
run: file scripts/flatten-rustdoc-json
97+
98+
- name: cargo docs (public only)
99+
run: cargo +nightly rustdoc --lib -- -Zunstable-options --output-format json
100+
101+
- name: flatten rustdoc json (public only)
102+
run: scripts/flatten-rustdoc-json > target/items-public-only.txt
103+
104+
- name: cargo docs (all)
105+
run: cargo +nightly rustdoc --lib -- -Zunstable-options --output-format json --document-private-items
106+
107+
- name: flatten rustdoc json (all)
108+
run: IGNORE_ITEMS='enum mdq::query::pest::Rule' scripts/flatten-rustdoc-json > target/items-all.txt
109+
110+
- name: compare
111+
run: |
112+
if diff -y --suppress-common-lines target/items-public-only.txt target/items-all.txt; then
113+
echo "::notice title=pub-vis::all pub items are actually public"
114+
else
115+
echo "::error title=pub-vis::some items marked pub are not actually public"
116+
exit 1
117+
fi

scripts/flatten-rustdoc-json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import json
5+
import sys
6+
7+
my_dir = os.path.dirname(os.path.realpath(__file__))
8+
repo_dir = os.path.abspath(os.path.join(my_dir, '..'))
9+
10+
DOCS_JSON_PATH = 'target/doc/mdq.json'
11+
12+
IGNORES = set([e for e in os.environ.get('IGNORE_ITEMS', '').split(',') if e])
13+
if IGNORES:
14+
print(f'Ignoring: {IGNORES}', file=sys.stderr)
15+
16+
with open(DOCS_JSON_PATH) as fh:
17+
docs_json = json.load(fh)
18+
19+
vis_by_item_id = {}
20+
path_by_item_id = {}
21+
kind_by_item_id = {}
22+
23+
for item_id, item in docs_json["index"].items():
24+
vis = item["visibility"] # this is the vis on the item itself, not the effective vis from mod.rs imports
25+
if isinstance(vis, dict) and ('restricted' in vis):
26+
vis = 'restricted'
27+
vis_by_item_id[item_id] = vis
28+
29+
for item_id, item in docs_json["paths"].items():
30+
kind_by_item_id[item_id] = item["kind"]
31+
path_by_item_id[item_id] = '::'.join(item["path"])
32+
33+
lines = []
34+
for item_id, vis in vis_by_item_id.items():
35+
if vis != 'public':
36+
continue
37+
item_kind = kind_by_item_id.get(item_id)
38+
item_path = path_by_item_id.get(item_id)
39+
if item_kind is None or item_path is None:
40+
continue
41+
line = f'{item_kind} {item_path}'
42+
if line in IGNORES:
43+
continue
44+
lines.append(line)
45+
46+
lines.sort()
47+
48+
for line in lines:
49+
print(line)
50+

src/md_elem/concatenate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub trait Concatenate: Sized {
1+
pub(crate) trait Concatenate: Sized {
22
fn try_concatenate(&mut self, other: Self) -> Result<(), Self>;
33

44
fn concatenate_similar(items: Vec<Self>) -> Vec<Self> {

src/md_elem/tree.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,9 @@ pub(crate) struct ReadOptions {
215215
/// [1]: https://example.com/one
216216
/// [1]: https://example.com/one
217217
/// ```
218-
pub validate_no_conflicting_links: bool,
218+
pub(crate) validate_no_conflicting_links: bool,
219219

220-
pub allow_unknown_markdown: bool,
220+
pub(crate) allow_unknown_markdown: bool,
221221
}
222222

223223
/// Various error conditions that can come from trying to parse Markdown.
@@ -1803,14 +1803,14 @@ mod tests {
18031803
use crate::util::utils_for_test::*;
18041804

18051805
impl MdContext {
1806-
pub fn empty() -> Self {
1806+
pub(crate) fn empty() -> Self {
18071807
Self {
18081808
footnotes: Default::default(),
18091809
empty_md_elems: vec![],
18101810
}
18111811
}
18121812

1813-
pub fn with<S: Into<FootnoteId>>(mut self, footnote_id: S, body: Vec<MdElem>) -> Self {
1813+
pub(crate) fn with<S: Into<FootnoteId>>(mut self, footnote_id: S, body: Vec<MdElem>) -> Self {
18141814
self.footnotes.insert(footnote_id.into(), body);
18151815
self
18161816
}

src/output/fmt_md.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl<'md> MdWriterState<'_, 'md> {
154154
}
155155
}
156156

157-
pub fn write_one_md<W>(&mut self, out: &mut Output<W>, node_ref: &'md MdElem)
157+
pub(crate) fn write_one_md<W>(&mut self, out: &mut Output<W>, node_ref: &'md MdElem)
158158
where
159159
W: SimpleWrite,
160160
{
@@ -528,7 +528,7 @@ enum DefinitionsToWrite {
528528
}
529529

530530
#[cfg(test)]
531-
pub mod tests {
531+
pub(crate) mod tests {
532532
use indoc::indoc;
533533

534534
use super::*;

src/output/fmt_md_inlines.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ pub(crate) struct MdInlinesWriter<'md> {
2626
}
2727

2828
struct PendingReferences<'md> {
29-
pub links: HashMap<LinkLabel<'md>, UrlAndTitle<'md>>,
30-
pub footnotes: HashSet<&'md FootnoteId>,
29+
links: HashMap<LinkLabel<'md>, UrlAndTitle<'md>>,
30+
footnotes: HashSet<&'md FootnoteId>,
3131
}
3232

3333
impl PendingReferences<'_> {
@@ -41,9 +41,9 @@ impl PendingReferences<'_> {
4141

4242
#[derive(Serialize, Debug, PartialEq, Eq, Copy, Clone, Hash)]
4343
pub(crate) struct UrlAndTitle<'md> {
44-
pub url: &'md String,
44+
pub(crate) url: &'md String,
4545
#[serde(skip_serializing_if = "Option::is_none")]
46-
pub title: &'md Option<String>,
46+
pub(crate) title: &'md Option<String>,
4747
}
4848

4949
#[derive(Debug, Copy, Clone)]
@@ -73,7 +73,7 @@ impl<'md> LinkLike<'md> for &'md Image {
7373
}
7474

7575
impl<'md> MdInlinesWriter<'md> {
76-
pub fn new(ctx: &'md MdContext, options: InlineElemOptions) -> Self {
76+
pub(crate) fn new(ctx: &'md MdContext, options: InlineElemOptions) -> Self {
7777
let pending_refs_capacity = 8; // arbitrary guess
7878
Self {
7979
ctx,
@@ -85,27 +85,27 @@ impl<'md> MdInlinesWriter<'md> {
8585
}
8686
}
8787

88-
pub fn has_pending_links(&self) -> bool {
88+
pub(crate) fn has_pending_links(&self) -> bool {
8989
!self.pending_references.links.is_empty()
9090
}
9191

92-
pub fn has_pending_footnotes(&self) -> bool {
92+
pub(crate) fn has_pending_footnotes(&self) -> bool {
9393
!self.pending_references.footnotes.is_empty()
9494
}
9595

96-
pub fn count_pending_links(&self) -> usize {
96+
pub(crate) fn count_pending_links(&self) -> usize {
9797
self.pending_references.links.len()
9898
}
9999

100-
pub fn count_pending_footnotes(&self) -> usize {
100+
pub(crate) fn count_pending_footnotes(&self) -> usize {
101101
self.pending_references.footnotes.len()
102102
}
103103

104-
pub fn drain_pending_links(&mut self) -> Vec<(LinkLabel<'md>, UrlAndTitle<'md>)> {
104+
pub(crate) fn drain_pending_links(&mut self) -> Vec<(LinkLabel<'md>, UrlAndTitle<'md>)> {
105105
self.pending_references.links.drain().collect()
106106
}
107107

108-
pub fn drain_pending_footnotes(&mut self) -> Vec<(String, &'md Vec<MdElem>)> {
108+
pub(crate) fn drain_pending_footnotes(&mut self) -> Vec<(String, &'md Vec<MdElem>)> {
109109
let mut result = Vec::with_capacity(self.pending_references.footnotes.len());
110110
let mut to_stringer = self.footnote_transformer.new_to_stringer();
111111

@@ -118,7 +118,7 @@ impl<'md> MdInlinesWriter<'md> {
118118
result
119119
}
120120

121-
pub fn write_line<I, W>(&mut self, out: &mut Output<W>, elems: I)
121+
pub(crate) fn write_line<I, W>(&mut self, out: &mut Output<W>, elems: I)
122122
where
123123
I: IntoIterator<Item = &'md Inline>,
124124
W: SimpleWrite,
@@ -128,7 +128,7 @@ impl<'md> MdInlinesWriter<'md> {
128128
}
129129
}
130130

131-
pub fn write_inline_element<W>(&mut self, out: &mut Output<W>, elem: &'md Inline)
131+
pub(crate) fn write_inline_element<W>(&mut self, out: &mut Output<W>, elem: &'md Inline)
132132
where
133133
W: SimpleWrite,
134134
{
@@ -269,7 +269,7 @@ impl<'md> MdInlinesWriter<'md> {
269269
///
270270
/// The `contents` function is what writes e.g. `an inline link` above. It's a function because it may be a recursive
271271
/// call into [write_line] (for links) or just simple text (for image alts).
272-
pub fn write_linklike<W, L>(&mut self, out: &mut Output<W>, link_like: L)
272+
pub(crate) fn write_linklike<W, L>(&mut self, out: &mut Output<W>, link_like: L)
273273
where
274274
W: SimpleWrite,
275275
L: LinkLike<'md> + Copy,
@@ -372,7 +372,7 @@ impl<'md> MdInlinesWriter<'md> {
372372
});
373373
}
374374

375-
pub fn write_url_title<W>(&mut self, out: &mut Output<W>, title: &Option<String>)
375+
pub(crate) fn write_url_title<W>(&mut self, out: &mut Output<W>, title: &Option<String>)
376376
where
377377
W: SimpleWrite,
378378
{
@@ -415,7 +415,7 @@ enum TitleQuote {
415415
}
416416

417417
impl TitleQuote {
418-
pub fn find_best_strategy(text: &str) -> Self {
418+
pub(crate) fn find_best_strategy(text: &str) -> Self {
419419
[Self::Double, Self::Single, Self::Paren]
420420
.into_iter()
421421
.find(|strategy| !strategy.has_conflicts(text))

src/output/fmt_plain_writer.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::cmp::min;
22
use std::io::Write;
33

4-
pub struct NewlineCollapser<W> {
4+
pub(crate) struct NewlineCollapser<W> {
55
max_newlines: usize,
66
underlying: W,
77
/// How many newlines are in this current stretch, or None if we haven't written anything yet.
@@ -12,22 +12,22 @@ impl<W> NewlineCollapser<W>
1212
where
1313
W: Write,
1414
{
15-
pub fn new(underlying: W, max_newlines: usize) -> Self {
15+
pub(crate) fn new(underlying: W, max_newlines: usize) -> Self {
1616
Self {
1717
max_newlines,
1818
underlying,
1919
current_newline_stretch: None,
2020
}
2121
}
2222

23-
pub fn have_pending_newlines(&self) -> bool {
23+
pub(crate) fn have_pending_newlines(&self) -> bool {
2424
match self.current_newline_stretch {
2525
None | Some(0) => false,
2626
Some(_) => true,
2727
}
2828
}
2929

30-
pub fn take_underlying(self) -> W {
30+
pub(crate) fn take_underlying(self) -> W {
3131
self.underlying
3232
}
3333

src/output/footnote_transform.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
use crate::util::output::{Output, SimpleWrite};
22
use std::collections::HashMap;
33

4-
pub struct FootnoteTransformer<'md> {
4+
pub(crate) struct FootnoteTransformer<'md> {
55
mappings: Option<HashMap<&'md str, usize>>,
66
}
77

8-
pub struct FootnoteTransformerToString<'a, 'md> {
8+
pub(crate) struct FootnoteTransformerToString<'a, 'md> {
99
transformer: &'a mut FootnoteTransformer<'md>,
1010
scratch: Output<String>,
1111
}
1212

1313
impl<'md> FootnoteTransformer<'md> {
14-
pub fn new(active: bool) -> Self {
14+
pub(crate) fn new(active: bool) -> Self {
1515
Self {
1616
mappings: if active { Some(HashMap::default()) } else { None },
1717
}
1818
}
1919

20-
pub fn write<W>(&mut self, out: &mut Output<W>, label: &'md str)
20+
pub(crate) fn write<W>(&mut self, out: &mut Output<W>, label: &'md str)
2121
where
2222
W: SimpleWrite,
2323
{
@@ -31,13 +31,13 @@ impl<'md> FootnoteTransformer<'md> {
3131
}
3232
}
3333

34-
pub fn new_to_stringer<'a>(&'a mut self) -> FootnoteTransformerToString<'a, 'md> {
34+
pub(crate) fn new_to_stringer<'a>(&'a mut self) -> FootnoteTransformerToString<'a, 'md> {
3535
FootnoteTransformerToString::new(self)
3636
}
3737
}
3838

3939
impl<'a, 'md> FootnoteTransformerToString<'a, 'md> {
40-
pub fn transform(&mut self, label: &'md str) -> String {
40+
pub(crate) fn transform(&mut self, label: &'md str) -> String {
4141
let len = self.transformed_label_len(label);
4242
_ = self.scratch.replace_underlying(String::with_capacity(len)).unwrap();
4343
self.transformer.write(&mut self.scratch, label);

src/output/link_transform.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub(crate) enum LinkLabel<'md> {
3636
}
3737

3838
impl<'md> LinkLabel<'md> {
39-
pub fn get_sort_string(&self, ctx: &'md MdContext) -> String {
39+
pub(crate) fn get_sort_string(&self, ctx: &'md MdContext) -> String {
4040
// There may be a way to Cow this so that we don't have to copy the ::Text string, but I can't find it.
4141
match self {
4242
LinkLabel::Text(s) => s.to_string(),
@@ -124,7 +124,7 @@ impl<'md> LinkTransformation<'md> {
124124
}
125125

126126
impl LinkTransformer {
127-
pub fn transform_variant(&self) -> LinkTransform {
127+
pub(crate) fn transform_variant(&self) -> LinkTransform {
128128
match self.delegate {
129129
LinkTransformState::Keep => LinkTransform::Keep,
130130
LinkTransformState::Inline => LinkTransform::Inline,

src/query/error.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ impl From<crate::query::Error> for InnerParseError {
9797

9898
/// Like a [pest::Span], but without a reference to the underlying `&str`, and thus cheaply Copyable.
9999
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Hash)]
100-
pub struct DetachedSpan {
101-
pub start: usize,
102-
pub end: usize,
100+
pub(crate) struct DetachedSpan {
101+
pub(crate) start: usize,
102+
pub(crate) end: usize,
103103
}
104104

105105
impl From<pest::Span<'_>> for DetachedSpan {

0 commit comments

Comments
 (0)