@@ -116,7 +116,7 @@ type Pinner interface {
116116
117117 // Unpin the given cid. If recursive is true, removes either a recursive or
118118 // a direct pin. If recursive is false, only removes a direct pin.
119- Unpin (ctx context.Context , cid cid.Cid , recursive bool ) error
119+ Unpin (ctx context.Context , cid cid.Cid , recursive bool , explain bool ) error
120120
121121 // Update updates a recursive pin from one cid to another
122122 // this is more efficient than simply pinning the new one and unpinning the
@@ -266,29 +266,59 @@ func (p *pinner) Pin(ctx context.Context, node ipld.Node, recurse bool) error {
266266var ErrNotPinned = fmt .Errorf ("not pinned" )
267267
268268// Unpin a given key
269- func (p * pinner ) Unpin (ctx context.Context , c cid.Cid , recursive bool ) error {
269+ func (p * pinner ) Unpin (ctx context.Context , c cid.Cid , recursive bool , explain bool ) error {
270270 p .lock .Lock ()
271271 defer p .lock .Unlock ()
272- reason , pinned , err := p .isPinnedWithType (c , Any )
272+
273+ var pinMode Mode
274+ if recursive {
275+ pinMode = Recursive
276+ } else {
277+ pinMode = Direct
278+ }
279+ _ , pinned , err := p .isPinnedWithType (c , pinMode )
273280 if err != nil {
274281 return err
275282 }
276- if ! pinned {
277- return ErrNotPinned
278- }
279- switch reason {
280- case "recursive" :
283+ if pinned {
281284 if recursive {
282285 p .recursePin .Remove (c )
283286 return nil
287+ } else {
288+ p .directPin .Remove (c )
289+ return nil
284290 }
285- return fmt .Errorf ("%s is pinned recursively" , c )
286- case "direct" :
287- p .directPin .Remove (c )
288- return nil
289- default :
290- return fmt .Errorf ("%s is pinned indirectly under %s" , c , reason )
291+ } else if recursive {
292+ _ , pinned , err := p .isPinnedWithType (c , Direct )
293+ if err != nil {
294+ return err
295+ }
296+ if pinned {
297+ p .directPin .Remove (c )
298+ return nil
299+ }
300+ }
301+
302+ if explain {
303+ reason , pinned , err := p .isPinnedWithType (c , Any )
304+ if err != nil {
305+ return err
306+ }
307+ if ! pinned {
308+ return ErrNotPinned
309+ }
310+ switch reason {
311+ case "recursive" :
312+ return fmt .Errorf ("%s is pinned recursively" , c )
313+ default :
314+ return fmt .Errorf ("%s is pinned indirectly under %s" , c , reason )
315+ }
316+ } else if recursive {
317+ return fmt .Errorf ("%s is not pinned recursively or directly" , c )
318+ } else {
319+ return fmt .Errorf ("%s is not pinned directly" , c )
291320 }
321+
292322}
293323
294324func (p * pinner ) isInternalPin (c cid.Cid ) bool {
0 commit comments