Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
6
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
P
pager-rs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
6
Issues
6
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Test Cases
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Cyril Plisko
pager-rs
Commits
3752c417
Commit
3752c417
authored
Sep 26, 2018
by
Cyril Plisko
🤔
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor to support Pager::with_default_pager()
parent
e234d005
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
134 additions
and
48 deletions
+134
-48
src/lib.rs
src/lib.rs
+134
-8
src/utils.rs
src/utils.rs
+0
-40
No files found.
src/lib.rs
View file @
3752c417
...
...
@@ -73,14 +73,22 @@ extern crate libc;
mod
utils
;
use
std
::
ffi
::
OsString
;
use
std
::
env
;
use
std
::
ffi
::{
OsStr
,
OsString
};
/// Default pager environment variable
const
DEFAULT_PAGER_ENV
:
&
str
=
"PAGER"
;
/// Environment variable to disable pager altogether
const
NOPAGER_ENV
:
&
str
=
"NOPAGER"
;
/// Last resort pager. Should work everywhere.
const
DEFAULT_PAGER
:
&
str
=
"more"
;
/// Keeps track of the current pager state
#[derive(Debug)]
pub
struct
Pager
{
default_pager
:
Option
<
OsString
>
,
pager
:
Option
<
OsString
>
,
on
:
bool
,
skip_on_notty
:
bool
,
...
...
@@ -89,7 +97,8 @@ pub struct Pager {
impl
Default
for
Pager
{
fn
default
()
->
Self
{
Self
{
pager
:
None
,
default_pager
:
None
,
pager
:
env
::
var_os
(
DEFAULT_PAGER_ENV
),
on
:
true
,
skip_on_notty
:
true
,
}
...
...
@@ -99,15 +108,13 @@ impl Default for Pager {
impl
Pager
{
/// Creates new instance of `Pager` with default settings
pub
fn
new
()
->
Self
{
Self
::
with_env
(
DEFAULT_PAGER_ENV
)
Default
::
default
(
)
}
/// Creates new instance of pager using `env` environment variable instead of PAGER
pub
fn
with_env
(
env
:
&
str
)
->
Self
{
let
pager
=
utils
::
find_pager
(
env
);
Self
{
pager
:
pager
,
pager
:
env
::
var_os
(
env
)
,
..
Default
::
default
()
}
}
...
...
@@ -117,10 +124,22 @@ impl Pager {
Self
::
with_env
(
env
)
}
/// Creates a new `Pager` instance with the specified default fallback
pub
fn
with_default_pager
<
S
>
(
pager
:
S
)
->
Self
where
S
:
Into
<
OsString
>
,
{
let
default_pager
=
Some
(
pager
.into
());
Self
{
default_pager
,
..
Default
::
default
()
}
}
/// Creates a new `Pager` instance directly specifying the desired pager
pub
fn
with_pager
(
pager
:
&
str
)
->
Self
{
Self
{
pager
:
OsString
::
from
(
pager
)
.into
(
),
pager
:
Some
(
pager
.into
()
),
..
Default
::
default
()
}
}
...
...
@@ -139,6 +158,19 @@ impl Pager {
self
.on
}
fn
pager
(
&
self
)
->
Option
<
OsString
>
{
let
fallback_pager
=
||
Some
(
OsStr
::
new
(
DEFAULT_PAGER
)
.into
());
if
env
::
var_os
(
NOPAGER_ENV
)
.is_some
()
{
None
}
else
{
self
.pager
.clone
()
.or_else
(||
self
.default_pager
.clone
())
.or_else
(
fallback_pager
)
}
}
/// Initiates Pager framework and sets up all the necessary environment for sending standard
/// output to the activated pager.
pub
fn
setup
(
&
mut
self
)
{
...
...
@@ -146,7 +178,7 @@ impl Pager {
self
.on
=
false
;
return
;
}
if
let
Some
(
ref
pager
)
=
self
.pager
{
if
let
Some
(
ref
pager
)
=
self
.pager
()
{
let
(
pager_stdin
,
main_stdout
)
=
utils
::
pipe
();
let
pid
=
utils
::
fork
();
match
pid
{
...
...
@@ -173,3 +205,97 @@ impl Pager {
}
}
}
#[cfg(test)]
mod
tests
{
use
super
::
*
;
use
std
::
ops
::
Drop
;
enum
PagerEnv
{
Reinstate
(
OsString
,
OsString
),
Remove
(
OsString
)
}
impl
PagerEnv
{
fn
new
<
S
:
AsRef
<
OsStr
>>
(
env
:
S
)
->
Self
{
let
env
=
env
.as_ref
()
.into
();
if
let
Some
(
value
)
=
env
::
var_os
(
&
env
)
{
PagerEnv
::
Reinstate
(
env
,
value
)
}
else
{
PagerEnv
::
Remove
(
env
)
}
}
fn
set
<
S
:
AsRef
<
OsStr
>>
(
&
self
,
value
:
S
)
{
match
self
{
|
PagerEnv
::
Reinstate
(
env
,
_
)
|
PagerEnv
::
Remove
(
env
)
=>
env
::
set_var
(
env
,
value
)
}
}
fn
remove
(
&
self
)
{
match
self
{
|
PagerEnv
::
Reinstate
(
env
,
_
)
|
PagerEnv
::
Remove
(
env
)
=>
env
::
remove_var
(
env
)
}
}
}
impl
Drop
for
PagerEnv
{
fn
drop
(
&
mut
self
)
{
match
self
{
PagerEnv
::
Reinstate
(
env
,
value
)
=>
env
::
set_var
(
env
,
value
),
PagerEnv
::
Remove
(
env
)
=>
env
::
remove_var
(
env
),
}
}
}
fn
assert_pager
(
pager
:
&
Pager
,
result
:
&
str
)
{
assert_eq!
(
pager
.pager
(),
Some
(
OsStr
::
new
(
result
)
.into
()));
}
#[test]
fn
nopager
()
{
let
nopager
=
PagerEnv
::
new
(
NOPAGER_ENV
);
nopager
.set
(
""
);
let
pager
=
Pager
::
new
();
assert
!
(
pager
.pager
()
.is_none
());
}
#[test]
fn
fallback_uses_more
()
{
let
pager
=
Pager
::
new
();
assert_pager
(
&
pager
,
DEFAULT_PAGER
);
}
#[test]
fn
with_default_pager_without_env
()
{
let
pagerenv
=
PagerEnv
::
new
(
DEFAULT_PAGER_ENV
);
pagerenv
.remove
();
let
pager
=
Pager
::
with_default_pager
(
"more_or_less"
);
assert_pager
(
&
pager
,
"more_or_less"
);
}
#[test]
fn
with_default_pager_with_env
()
{
let
pagerenv
=
PagerEnv
::
new
(
DEFAULT_PAGER_ENV
);
pagerenv
.set
(
"something_else"
);
let
pager
=
Pager
::
with_default_pager
(
"more_or_less"
);
assert_pager
(
&
pager
,
"something_else"
);
}
#[test]
fn
with_default_pager
()
{
let
pager
=
Pager
::
with_default_pager
(
"more_or_less"
);
assert_pager
(
&
pager
,
"more_or_less"
);
}
#[test]
fn
with_pager
()
{
let
pager
=
Pager
::
with_pager
(
"now_or_never"
);
assert_pager
(
&
pager
,
"now_or_never"
);
}
}
src/utils.rs
View file @
3752c417
use
std
::
env
;
use
std
::
ffi
::{
CString
,
OsString
};
use
std
::
os
::
unix
::
ffi
::
OsStringExt
;
use
std
::
ptr
;
...
...
@@ -51,42 +50,3 @@ pub fn isatty(fd: i32) -> bool {
let
isatty
=
unsafe
{
libc
::
isatty
(
fd
)
};
isatty
!=
0
}
#[cfg(test)]
mod
tests
{
use
super
::
*
;
const
MORE
:
&
str
=
"/bin/more"
;
fn
assert_ends_with_bin_more
(
more
:
OsString
)
{
let
good
=
more
.to_str
()
.map
(|
m
|
m
.ends_with
(
MORE
))
.unwrap_or
(
false
);
assert
!
(
good
,
"{:?} doesn't end with {}"
,
more
,
MORE
);
}
#[test]
fn
more_found_in_path
()
{
assert
!
(
which
(
"more"
)
.is_some
())
}
#[test]
fn
erom_not_found_in_path
()
{
assert
!
(
which
(
"erom"
)
.is_none
())
}
#[test]
fn
which_more
()
{
which
(
"more"
)
.map
(
assert_ends_with_bin_more
);
}
#[test]
fn
usr_bin_more_default_pager
()
{
find_pager
(
"__RANDOM_NAME"
)
.map
(
assert_ends_with_bin_more
);
}
#[test]
fn
nopager
()
{
env
::
set_var
(
"NOPAGER"
,
""
);
assert
!
(
find_pager
(
"more"
)
.is_none
());
env
::
remove_var
(
"NOPAGER"
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment