1 module git.object_;
2 
3 import git.oid;
4 import git.repository;
5 import git.types;
6 import git.util;
7 
8 import git2.object_;
9 import git2.types;
10 
11 // Note: This file includes none of the original comments, as they might
12 // be copyrightable material.
13 
14 ///
15 struct GitObject
16 {
17     // Internal, see free-standing constructor functions below.
18     private this(GitRepo repo, git_object* obj)
19     {
20         _repo = repo;
21         _data = Data(obj);
22     }
23 
24     ///
25     @property GitOid id()
26     {
27         return GitOid(*git_object_id(_data._payload));
28     }
29 
30     ///
31     @property GitType type()
32     {
33         return cast(GitType)git_object_type(_data._payload);
34     }
35 
36     ///
37     @property GitRepo owner()
38     {
39         return GitRepo(git_object_owner(_data._payload));
40     }
41 
42     ///
43     @property GitObject dup()
44     {
45         git_object* result;
46         require(git_object_dup(&result, _data._payload) == 0);
47         return GitObject(_repo, result);
48     }
49 
50     ///
51     @property GitObject peel(GitType targetType)
52     {
53         git_object* result;
54         require(git_object_peel(&result, _data._payload, cast(git_otype)targetType) == 0);
55         return GitObject(_repo, result);
56     }
57 
58 package:
59     /**
60      * The internal libgit2 handle for this object.
61      *
62      * Care should be taken not to escape the reference outside a scope where
63      * a GitObject encapsulating the handle is kept alive.
64      */
65     @property git_object* cHandle()
66     {
67         return _data._payload;
68     }
69 
70 private:
71     struct Payload
72     {
73         this(git_object* payload)
74         {
75             _payload = payload;
76         }
77 
78         ~this()
79         {
80             if (_payload !is null)
81             {
82                 git_object_free(_payload);
83                 _payload = null;
84             }
85         }
86 
87         /// Should never perform copy
88         @disable this(this);
89 
90         /// Should never perform assign
91         @disable void opAssign(typeof(this));
92 
93         git_object* _payload;
94     }
95 
96     // Reference to the parent repository to keep it alive.
97     GitRepo _repo;
98 
99     import std.typecons : RefCounted, RefCountedAutoInitialize;
100     alias RefCounted!(Payload, RefCountedAutoInitialize.no) Data;
101     Data _data;
102 }
103 
104 ///
105 GitObject lookup(GitRepo repo, GitOid oid, GitType type = GitType.any)
106 {
107     git_object* result;
108     auto cOid = oid._get_oid;
109     require(git_object_lookup(&result, repo.cHandle, &cOid, cast(git_otype)type) == 0);
110     return GitObject(repo, result);
111 }
112 
113 ///
114 GitObject lookupByPrefix(GitRepo repo, GitOid oid, size_t prefixLen, GitType type = GitType.any)
115 {
116     git_object* result;
117     auto cOid = oid._get_oid;
118     require(git_object_lookup(&result, repo.cHandle, &cOid, cast(git_otype)type) == 0);
119     return GitObject(repo, result);
120 }
121 
122 ///
123 GitObject lookup(GitRepo repo, in char[] hexString, GitType type = GitType.any)
124 {
125     auto oid = GitOid(hexString);
126     if (hexString.length < GitOid.MaxHexSize)
127     {
128         return lookupByPrefix(repo, oid, hexString.length, type);
129     }
130     else
131     {
132         return lookup(repo, oid, type);
133     }
134 }
135 
136 ///
137 const(char)[] toString(GitType type)
138 {
139     return git_object_type2string(cast(git_otype)type).toSlice;
140 }
141 
142 ///
143 GitType toType(in char[] str)
144 {
145     return cast(GitType)git_object_string2type(str.gitStr);
146 }
147 
148 ///
149 bool isLoose(GitType type)
150 {
151     return git_object_typeisloose(cast(git_otype)type) != 0;
152 }
153 
154 /+
155 extern (C):
156 size_t git_object__size(git_otype type);
157 +/