Skip to content

Commit faf01b0

Browse files
committed
Added example for fixpointed to-directory-tree command
1 parent cbb0e93 commit faf01b0

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
-- This is an example on how to build a directory tree using the so-called
2+
-- fixpointed method. See the documenatation of the `Dhall.DirectoryTree` module
3+
-- for further information on it.
4+
5+
-- First, define some types recognized by the `dhall to-directory-tree` command.
6+
7+
-- A user, either identified by its numeric user id or its name.
8+
let User = < UserId : Natural | UserName : Text >
9+
10+
-- Similarly, a group.
11+
let Group = < GroupId : Natural | GroupName : Text >
12+
13+
-- The following two type aliases are a well-typed represenation of the bitmask
14+
-- for permissions used by the DAC access control found on Unix systems. See for
15+
-- example the chmod(5) manual entry.
16+
17+
-- How much access we do grant...
18+
let Access =
19+
{ execute : Optional Bool, read : Optional Bool, write : Optional Bool }
20+
21+
-- ... for whom.
22+
let Mode =
23+
{ user : Optional Access
24+
, group : Optional Access
25+
, other : Optional Access
26+
}
27+
28+
-- A generic file system entry. It consists of a name, an abstract content and
29+
-- some metadata which might be set (Some) or not (None).
30+
let Entry =
31+
\(content : Type) ->
32+
{ name : Text
33+
, content : content
34+
, user : Optional User
35+
, group : Optional Group
36+
, mode : Optional Mode
37+
}
38+
39+
-- This is the main program constructing our directory tree. It is a fixpoint
40+
-- definition similar to how we deal with recursive types in arbitrary Dhall
41+
-- programs but specialised to our use case. The first argument is the type of a
42+
-- directory tree and the second one is a record where each field is a
43+
-- constructor for a specific filesystem entry.
44+
in \(tree : Type) ->
45+
\ ( make
46+
: { directory : Entry (List tree) -> tree, file : Entry Text -> tree }
47+
) ->
48+
49+
-- Before we define the actual directory tree we define some Dhall schemas
50+
-- and shortcuts for convenience.
51+
52+
-- A schema suitable for a directory...
53+
let Directory =
54+
{ Type =
55+
{ name : Text
56+
, content : List tree
57+
, user : Optional User
58+
, group : Optional Group
59+
, mode : Optional Mode
60+
}
61+
, default =
62+
{ content = [] : List tree
63+
, user = None User
64+
, group = None Group
65+
, mode = None Mode
66+
}
67+
}
68+
69+
-- ... and one for a file.
70+
let File =
71+
{ Type =
72+
{ name : Text
73+
, content : Text
74+
, user : Optional User
75+
, group : Optional Group
76+
, mode : Optional Mode
77+
}
78+
, default =
79+
{ content = ""
80+
, user = None User
81+
, group = None Group
82+
, mode = None Mode
83+
}
84+
}
85+
86+
-- Give someone full access to an filesystem entry.
87+
let full_access
88+
: Access
89+
= { execute = Some True, read = Some True, write = Some True }
90+
91+
-- Give someone no access at all to an filesystem entry.
92+
let no_access
93+
: Access
94+
= { execute = Some False, read = Some False, write = Some False }
95+
96+
-- These permissions
97+
-- * grant full access to the user.
98+
-- * retain the permissions of the primary group of the user.
99+
-- * deny access to everyone else.
100+
let semi_private
101+
: Mode
102+
= { user = Some full_access, group = None Access, other = Some no_access }
103+
104+
-- Now let's start with the directory tree ...
105+
in [ -- Some file with a gentle greeting. No metadata is set explicitly.
106+
make.file File::{ name = "some file", content = "Hello world!" }
107+
-- A directory with some metadata set explicitely.
108+
, make.directory
109+
Directory::{
110+
, name = "my private directory"
111+
-- How owns the new directory: just_me
112+
, user = Some (User.UserName "just_me")
113+
-- We stick with the user's default group here.
114+
, group = None Group
115+
, mode = Some semi_private
116+
, content = [] : List tree
117+
}
118+
]
119+
: List tree

0 commit comments

Comments
 (0)